CI Framework Source code read Note 6 extension hook hook.php

Source: Internet
Author: User
Tags codeigniter

The CI framework allows you to add or change the core functions of the system (such as rewriting the cache, output, etc.) without altering the core code of the system.

For example, under the condition of the system opening hook (config.php $config[‘enable_hooks‘] = TRUE; ). By adding a specific hook, you can have the system trigger a specific script at a specific moment:

$hook Array (    ' class '     = ' framelog ',    ' function '  = ' postlog ',    ' filename '  = ' post_ ') System.php ',    ' filepath '   = ' hooks ',);

The hooks above define a post_system hook. Script processing after the last page rendering (the meaning of the parameters can be used to refer to the following or manual. There are not many other explanations to be done here temporarily.)

So here's the question:

    1. What is a hook?
    2. What are the hooks supported in CI?
    3. How is the hook in CI implemented?

We take a step-by-step look.

1.What is a hook?

Baidu Encyclopedia on the definition of hooks is:

A hook is actually a program segment that processes messages through a system call. Hang it into the system. Whenever a particular message is issued, the hook program captures the message before the destination form is reached, i.e. the hook function gets control first. The hook function is then able to process (change) the message. can also continue to pass the message without processing. It is also possible to force the end of message delivery.

From the above definition we can see the points:

    1. A hook is an event-driven pattern. Its core nature is the event (CI pre_system,pre_controller, etc. are specific events).

    2. Since it is event-driven, it must include the two most important steps: (1), event registration. In the case of hooks, the hook hooks are mounted. (2). event triggering .

      Call a specific hook at a specific point in time to run the corresponding hook program.

    3. Since it is event driven. Then you should also support multiple registration events for the unified hooking point.
    4. After starting the hook hook, the process of the program may change, and the hooks may have the possibility of mutual invocation, assuming that improper handling, there will be the possibility of a dead loop. At the same time, the activation of the hooks makes the program somewhat complex and difficult to debug.

2. Pre-defined hooks in CI

There are 7 preset hook-up points available in CI, each of which:

Pre_system: refers to the hook in the pre-loading system

Pre_controller: call controller before the hook, Routing and Security check has been completed

post_controller_constructor: after controller instantiation, no matter what method is called before

Post_controller: After the controller is completely executed

display_override: rewrite display

cache_override: overriding the cache

Post_system: After the page is finally sent to the client

3. Implementation of hooks in CI

The core function of the hooks in CI is that the hook component is finished, and the class diagram of the component is first seen:

Of

enabled: The flag of whether the hook function is turned on.

Hooks : Save the list of hooks enabled in the system

in_progress: Then we will see that this flag bit is used to prevent the loop of loops caused by calls to each other between hooks.

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

_call_hook: Calls _run_hook to call the specified hook program.

Before the codeigniter.php we have seen. _call_hook is an interface that is actually provided to an external call.

_run_hook: The function that actually runs the hook program

Before we start, we first post a structure that defines the hooks in advance.

This structure may be consistent throughout the source code, so it is necessary to know the meaning of the parameters of the structure.

$hook Array (          The class name called by the ' class '//Hook.) can be null    ' function '  = ' xx ',/ / hook Call of functions name    ' filename '  = ' xx ',//  The hook's file name    ' filepath '   = ' xx ',// The folder    ' params ' of the hooks   = > ' xx '// pass to the hook for the number of references );

1). Hook Component Initialization

The _initialize function is used for the initialization of the hook component, and the function is mainly completed with the following tasks:

(1) Check whether the hook function is enabled in the configuration file. This needs to be loaded in config (Configuration management component):

$CFG =& load_class (' Config ', ' core '), if ($CFG->item (' enable_hooks ') = = FALSE) {return;}

(2) Loading a list of defined hooks

Similarly, you can set different environment to enable different hooks, assuming there are, priority loading into the hooks under envrionment :

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 ');}

(3) Check the hook. If no hooks are set, or if the hook format is incorrect, no matter what processing, exit directly:

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

After initialize, the list of hooks that have already been defined is stored in hook::hooks:

$this->hooks =& $hook;

2. Call-Specified hooks

_call_hook is the interface that is called directly in the main program. The basic work of this interface is:

(1). Check that the hooks are enabled and that the call's hooks are defined in advance (assuming that the hooks are not enabled or call does not exist.) return directly):

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

(2). Check whether the same hook point has multiple hooks enabled, fake. Then run it in turn:

if (Isset ($this->hooks[$which][0]) and Is_array ($this->hooks[$which][0]) {foreach ($this->hooks[$which] As $val) {$this->_run_hook ($val);}}

(3). otherwise. There is only one hook. Run it

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

_run_hook is the function that actually runs the hook.

3. Run a specific Hook program

The _run_hook function is the actual runner of the hook. The function receives an array of pre-defined hooks as the number of parameters. Implementations such as the following:

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

if (! Is_array ($data)) {return FALSE;}

(2). Check the hook running status.

The in_progress is used to flag the current hook's running state. The main function of this parameter is to prevent the loop of loops caused by mutual calls between hooks.

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

(3). Check the legality of hooks.

To facilitate the narration, we once again present a required number of parameters for a pre-defined hook:

$hook Array (         The class name of the ' class '// hook call, which can be null    ' function '  = ' xx ',//  The function name of the hook call    ' filename '  = ' xx ',// The hook's file name    ' filepath '   = ' xx ', // folder for hooks    ' Params '   = = ' xx '/// The number of the parameters passed to the hook );

The class and params are optional, and the other 3 parameters are required. If it is not provided, it can only be returned directly because it cannot be accurately located to the hook program:

if (! isset ($data [' filepath ']) OR! isset ($data [' filename ']) {return FALSE;} $filepath = APPPATH. $data [' filepath ']. ' /'. $data [' filename '];if (! file_exists ($filepath)) {return FALSE;}

(4). Get here. Has basically confirmed the location of the hook program, here are two things:

A. The class number in the hook defined in advance is empty. Indicates that a procedure is used to invoke the method. The function xxx in the hook file is run directly

B. Class parameters are not NULL, provided is an object-oriented approach, the actual hook program is $class-> $function. The same, assuming that neither the class nor the function parameters are set, the hook cannot be run. Direct return:

$class = false; $function = false; $params = ";/* Get Hook Class */if (Isset ($data [' class]) and $data [' class ']! = ') {$class = $data [' class '];} /* Get hook function */if (isset ($data [' function])) {$function = $data [' function '];} /* Get the number of hooks passed */if (isset ($data [' params ')]) {$params = $data [' params '];} /* If neither class nor function exists, you cannot locate the hook program and return */if directly ($class = = = False and $function = = = False) {return false;}

(5). Set the run flag in_progress. and run the hooks for both of these cases:

/* Object-oriented setting */if ($class!== FALSE) {if (! class_exists ($class)) {require ($filepath);} $HOOK = new $class, $HOOK-$function ($params);} Else{if (! function_exists ($function)) {require ($filepath);} $function ($params);}

Finally, don't forget to set the identity bit in_progress to false after the hook has finished running, and return the flag to run successfully:

$this->in_progress = False;return TRUE;

The complete source code for the hook component:

<?

PHP if (! defined (' BasePath ')) exit (' No Direct script access allowed '); class Ci_hooks {/** * determines wether Hooks is Enabled * * @var bool */var $enabled = false;/** * List of all hooks set in config/hooks.php * */var $hooks = array ();/** * Determines wether hook is in progress, used to prevent infinte loops * */var $in _progress= false;/** * Constructor */func tion __construct () {$this->_initialize (); Log_message (' Debug ', ' Hooks Class Initialized ');} /** * Initialize the Hooks Preferences * * @accessprivate * @returnvoid */function _initialize () {$CFG =& load_class (' C Onfig ', ' core ');//If hooks is not enabled in the config file//there was nothing else to Doif ($CFG->item (' Enable_hook s ') = = 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 * * @accessprivate * @paramstringthe Hook name * @returnmixed */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 * * @accessprivate * @paramarraythe Hook Details * @returnbool */function _run_h Ook ($data) {if (! Is_array ($data)) {return FALSE;} If the script being called happens to has the same hook call within it a loop can happenif ($this->in_progress = = T RUE) {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 functionif ($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;}}

References

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

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

3. Layout of the http://codeigniter.org.cn/forums/thread-4947-1-1.html hook implementation

CI Framework Source code read Note 6 extension hook hook.php

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.