Table of Contents
CI framework source code reading notes 6 Extension hooks Hook.php, cihook.php
1. What is a hook
2. Predefined hooks in CI
3. Implementation of hooks in CI
参考文献
CI框架引入模板问题
CI框架 怎实现统计网站点击量,哪位把源码发我跪
Home Backend Development PHP Tutorial CI framework source code reading notes 6 Extension hook Hook.php, cihook.php_PHP tutorial

CI framework source code reading notes 6 Extension hook Hook.php, cihook.php_PHP tutorial

Jul 13, 2016 am 10:14 AM
hook Expand frame Source code notes hook read

CI framework source code reading notes 6 Extension hooks Hook.php, cihook.php

The CI framework allows you to add or change the system without modifying the core code of the system. core functions (such as rewriting cache, output, etc.). For example, if hooks are enabled in the system ($config['enable_hooks'] = TRUE; in config.php), by adding specific hooks, the system can trigger specific scripts at specific times:

<span>$hook</span>['post_system'] = <span>array</span><span>(
    </span>'class'     => 'frameLog',
    'function'  => 'postLog',
    'filename'  => 'post_system.php',
    'filepath'   => 'hooks',<span>
);</span>
Copy after login

The above hook defines a post_system hook, which is used for script processing after the final page rendering (the meaning of the parameters can be referred to later or in the manual, and no further explanation will be given here for the time being).

Then the question is:

Let’s look at it step by step.

1. What is a hook

The definition of hook on Baidu Encyclopedia is:

<p><span>钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。</span></p>
Copy after login

We can see several points from the above definition:

2. Predefined hooks in CI

CI provides 7 available preset hook points, which are:

pre_system: refers to the hook in the early stage of system loading

pre_controller: The hook before calling the controller, routing and security checks have been completed

post_controller_constructor: After the controller is instantiated and before any method is called

post_controller: After the controller is fully running

 display_override: override display

cache_override: Rewrite cache

post_system: After the final page is sent to the client

3. Implementation of hooks in CI

The core function of hooks in CI is completed by the Hook component. Let’s look at the class diagram of this component first:

Among them:

enabled: Flag indicating whether the hook function is enabled.

Hooks: Save the list of hooks enabled in the system

in_progress: We will see later that this flag is used to prevent infinite loops caused by mutual calls between hooks.

_construct is the constructor of the Hook component, which calls _initialize to complete the initialization work

 _call_hook: Call _run_hook to call the specified hook program. We have seen before in CodeIgniter.php that _call_hook is the interface actually provided for external calls.

 _run_hook: The function that actually executes the hook program

Before we start, let’s post the structure of the predefined hook. This structure may appear throughout the source code, so we need to know the meaning of the parameters of this structure.

<span>$hook</span>['xx'] = <span>array</span><span>(
    </span>'class'     => 'xx', <span>//</span><span>钩子调用的类名,可以为空</span>
    'function'  => 'xx',<span>//</span><span>钩子调用的函数名</span>
    'filename'  => 'xx',<span>//</span><span>该钩子的文件名</span>
    'filepath'   => 'xx',<span>//</span><span>钩子的目录</span>
    'params'   => 'xx'<span>//</span><span>传递给钩子的参数</span>
);
Copy after login
Copy after login

1. Hook component initialization

_initialize function is used to initialize the hook component. The main tasks of this function are:

(1) Check whether the hook function in the configuration file is enabled, which requires loading Config (configuration management component):

$CFG =& load_class('Config', 'core');

if ($CFG->item('enable_hooks') == FALSE)
{
	return;
}
Copy after login

(2) Load the defined hook list

Similarly, you can set different ENVIRONMENT to enable different hooks. If there are any, the hooks under ENVRIONMENT will be loaded first:

if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
    include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
elseif (is_file(APPPATH.'config/hooks.php'))
{
	include(APPPATH.'config/hooks.php');
}
Copy after login

(3) Hook inspection. If no hook is set, or the hook format is wrong, no processing will be done and you will exit directly:

if ( ! isset($hook) OR ! is_array($hook))
{
	return;
}
Copy after login

After initialize, the defined hook list is stored in Hook::hooks:

$this->hooks =& $hook;
Copy after login

2. Call specified hook

_call_hook is the interface directly called in the main program. The main tasks of this interface are:

(1). Check whether the hook is enabled and whether the call hook is predefined (if it is not enabled or the call hook does not exist, it will return directly):

if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
	return FALSE;
}
Copy after login

(2). Check whether multiple hooks are enabled on the same hook point. If so, execute them in sequence:

if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
{
	foreach ($this->hooks[$which] as $val)
	{
		$this->_run_hook($val);
	}
}
Copy after login

(3). Otherwise, there is only one hook, execute it

else
{
	$this->_run_hook($this->hooks[$which]);
}
Copy after login

_run_hook is the function that actually executes the hook.

3. run to execute a specific hook program

The

_run_hook function is the actual executor of hook. This function receives a predefined hook array as a parameter and is implemented as follows:

(1). If the parameter passed is not an array at all (naturally it is not a valid hook), then return directly:

if ( ! is_array($data))
{
	return FALSE;
}
Copy after login

(2). 检查hook执行状态。

in_progress用于标志当前hook的执行状态。这个参数的主要作用,是防止hook之间的相互调用而导致的死循环。

if ($this->in_progress == TRUE)
{
	return;
}
Copy after login

(3). Hook的合法性检查。

为了方便讲述,我们再次提出一个预定义的hook需要的参数:

<span>$hook</span>['xx'] = <span>array</span><span>(
    </span>'class'     => 'xx', <span>//</span><span>钩子调用的类名,可以为空</span>
    'function'  => 'xx',<span>//</span><span>钩子调用的函数名</span>
    'filename'  => 'xx',<span>//</span><span>该钩子的文件名</span>
    'filepath'   => 'xx',<span>//</span><span>钩子的目录</span>
    'params'   => 'xx'<span>//</span><span>传递给钩子的参数</span>
);
Copy after login
Copy after login

其中class和params是可选参数,其他3个参数为必选参数,如果不提供,则由于无法准确定位到hook程序,只能直接返回:

if ( ! isset($data['filepath']) OR ! isset($data['filename']))
{
	return FALSE;
}

$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];

if ( ! file_exists($filepath))
{
	return FALSE;
}
Copy after login

(4). 到这里,已经基本确认钩子程序的位置了,这里有两种情况:

a. 预定义的hook中class参数为空,表明使用的是过程式的调用方式,则直接执行hook文件中的function xxx

b. class参数不为空,提供的是面向对象的方式,则实际的钩子程序是$class->$function .同样,如果既没有设置class,也没有设置function参数,则无法执行hook,直接返回:

$class		= FALSE;
$function	= FALSE;
$params		= '';

/* 获取 hook class */
if (isset($data['class']) AND $data['class'] != '')
{
	$class = $data['class'];
}

/* 获取 hook function */
if (isset($data['function']))
{
	$function = $data['function'];
}

/* 获取传递的 hook 参数 */
if (isset($data['params']))
{
	$params = $data['params'];
}

/* 如果class和function都不存在,则无法定位hook程序,直接返回 */
if ($class === FALSE AND $function === FALSE)
{
	return FALSE;
}
Copy after login

(5). 设置执行标志in_progress,并执行上述两种情况下的hook:

/* 面向对象的设置方式 */
if ($class !== FALSE)
{
	if ( ! class_exists($class))
	{
		require($filepath);
	}

	$HOOK = new $class;
	$HOOK->$function($params);
}
/*  过程式的执行方式 */
else
{
	if ( ! function_exists($function))
	{
		require($filepath);
	}

	$function($params);
}
Copy after login

最后,别忘了在hook执行完之后,设置标识位in_progress为false,并返回执行成功的标志:

$this->in_progress = FALSE;
return TRUE;
Copy after login

Hook组件的完整源码:

_initialize();
		log_message('debug', "Hooks Class Initialized");
	}

	/**
	 * Initialize the Hooks Preferences
	 *
	 * @access	private
	 * @return	void
	 */
	function _initialize()
	{
		$CFG =& load_class('Config', 'core');

		// If hooks are not enabled in the config file
		// there is nothing else to do

		if ($CFG->item('enable_hooks') == FALSE)
		{
			return;
		}

		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
		{
		    include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
		}
		elseif (is_file(APPPATH.'config/hooks.php'))
		{
			include(APPPATH.'config/hooks.php');
		}

		if ( ! isset($hook) OR ! is_array($hook))
		{
			return;
		}

		$this->hooks =& $hook;
		$this->enabled = TRUE;
	}

	/**
	 * Call Hook
	 *
	 * Calls a particular hook
	 *
	 * @access	private
	 * @param	string	the hook name
	 * @return	mixed
	 */
	function _call_hook($which = '')
	{
		if ( ! $this->enabled OR ! isset($this->hooks[$which]))
		{
			return FALSE;
		}

		if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
		{
			foreach ($this->hooks[$which] as $val)
			{
				$this->_run_hook($val);
			}
		}
		else
		{
			$this->_run_hook($this->hooks[$which]);
		}

		return TRUE;
	}

	/**
	 * Run Hook
	 *
	 * Runs a particular hook
	 *
	 * @access	private
	 * @param	array	the hook details
	 * @return	bool
	 */
	function _run_hook($data)
	{
		if ( ! is_array($data))
		{
			return FALSE;
		}

		// If the script being called happens to have the same hook call within it a loop can happen

		if ($this->in_progress == TRUE)
		{
			return;
		}

		if ( ! isset($data['filepath']) OR ! isset($data['filename']))
		{
			return FALSE;
		}

		$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];

		if ( ! file_exists($filepath))
		{
			return FALSE;
		}


		$class		= FALSE;
		$function	= FALSE;
		$params		= '';

		if (isset($data['class']) AND $data['class'] != '')
		{
			$class = $data['class'];
		}

		if (isset($data['function']))
		{
			$function = $data['function'];
		}

		if (isset($data['params']))
		{
			$params = $data['params'];
		}

		if ($class === FALSE AND $function === FALSE)
		{
			return FALSE;
		}

		$this->in_progress = TRUE;

		// Call the requested class and/or function
		if ($class !== FALSE)
		{
			if ( ! class_exists($class))
			{
				require($filepath);
			}

			$HOOK = new $class;
			$HOOK->$function($params);
		}
		else
		{
			if ( ! function_exists($function))
			{
				require($filepath);
			}

			$function($params);
		}

		$this->in_progress = FALSE;
		return TRUE;
	}

}
Copy after login

参考文献

1.  http://codeigniter.org.cn/user_guide/general/hooks.html   手册

2.  http://itopic.org/codeigniter-hook.html  

3.  http://codeigniter.org.cn/forums/thread-4947-1-1.html  钩子实现的Layout

CI框架引入模板问题

这个……好像CI没啥方法,倒是可以通过写模板的时候include进去header.php和footer.php,倒是还有听说smarty模板引擎中有模板继承这个概念,可以让你的内容页继承某个页面,那个页面上写着header.php和footer.php,貌似CI是可以使用smarty模板引擎的,不过我没有那样用过,还有,CI有hook(钩子)这个东西,老实说我没用过,不知道它能不能实现。
 

CI框架 怎实现统计网站点击量,哪位把源码发我跪

是记录有多少人进去你的网站还是说点击的某个连接多少次?
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/908124.htmlTechArticleCI框架源码阅读笔记6 扩展钩子 Hook.php,cihook.php CI框架允许你在不修改系统核心代码的基础上添加或者更改系统的核心功能(如重写缓存、...
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to evaluate the cost-effectiveness of commercial support for Java frameworks How to evaluate the cost-effectiveness of commercial support for Java frameworks Jun 05, 2024 pm 05:25 PM

Evaluating the cost/performance of commercial support for a Java framework involves the following steps: Determine the required level of assurance and service level agreement (SLA) guarantees. The experience and expertise of the research support team. Consider additional services such as upgrades, troubleshooting, and performance optimization. Weigh business support costs against risk mitigation and increased efficiency.

How do the lightweight options of PHP frameworks affect application performance? How do the lightweight options of PHP frameworks affect application performance? Jun 06, 2024 am 10:53 AM

The lightweight PHP framework improves application performance through small size and low resource consumption. Its features include: small size, fast startup, low memory usage, improved response speed and throughput, and reduced resource consumption. Practical case: SlimFramework creates REST API, only 500KB, high responsiveness and high throughput

Golang framework documentation best practices Golang framework documentation best practices Jun 04, 2024 pm 05:00 PM

Writing clear and comprehensive documentation is crucial for the Golang framework. Best practices include following an established documentation style, such as Google's Go Coding Style Guide. Use a clear organizational structure, including headings, subheadings, and lists, and provide navigation. Provides comprehensive and accurate information, including getting started guides, API references, and concepts. Use code examples to illustrate concepts and usage. Keep documentation updated, track changes and document new features. Provide support and community resources such as GitHub issues and forums. Create practical examples, such as API documentation.

How to choose the best golang framework for different application scenarios How to choose the best golang framework for different application scenarios Jun 05, 2024 pm 04:05 PM

Choose the best Go framework based on application scenarios: consider application type, language features, performance requirements, and ecosystem. Common Go frameworks: Gin (Web application), Echo (Web service), Fiber (high throughput), gorm (ORM), fasthttp (speed). Practical case: building REST API (Fiber) and interacting with the database (gorm). Choose a framework: choose fasthttp for key performance, Gin/Echo for flexible web applications, and gorm for database interaction.

How does the learning curve of PHP frameworks compare to other language frameworks? How does the learning curve of PHP frameworks compare to other language frameworks? Jun 06, 2024 pm 12:41 PM

The learning curve of a PHP framework depends on language proficiency, framework complexity, documentation quality, and community support. The learning curve of PHP frameworks is higher when compared to Python frameworks and lower when compared to Ruby frameworks. Compared to Java frameworks, PHP frameworks have a moderate learning curve but a shorter time to get started.

Performance comparison of Java frameworks Performance comparison of Java frameworks Jun 04, 2024 pm 03:56 PM

According to benchmarks, for small, high-performance applications, Quarkus (fast startup, low memory) or Micronaut (TechEmpower excellent) are ideal choices. SpringBoot is suitable for large, full-stack applications, but has slightly slower startup times and memory usage.

Detailed practical explanation of golang framework development: Questions and Answers Detailed practical explanation of golang framework development: Questions and Answers Jun 06, 2024 am 10:57 AM

In Go framework development, common challenges and their solutions are: Error handling: Use the errors package for management, and use middleware to centrally handle errors. Authentication and authorization: Integrate third-party libraries and create custom middleware to check credentials. Concurrency processing: Use goroutines, mutexes, and channels to control resource access. Unit testing: Use gotest packages, mocks, and stubs for isolation, and code coverage tools to ensure sufficiency. Deployment and monitoring: Use Docker containers to package deployments, set up data backups, and track performance and errors with logging and monitoring tools.

Golang framework performance comparison: metrics for making wise choices Golang framework performance comparison: metrics for making wise choices Jun 05, 2024 pm 10:02 PM

When choosing a Go framework, key performance indicators (KPIs) include: response time, throughput, concurrency, and resource usage. By benchmarking and comparing frameworks' KPIs, developers can make informed choices based on application needs, taking into account expected load, performance-critical sections, and resource constraints.

See all articles