CI framework source code reading notes 6 extended Hook. php

Source: Internet
Author: User
CI framework source code reading Note 6 extended Hook. php CI framework allows you to add or change the core functions of the system (such as rewriting cache and output) without modifying the core code of the system ). For example. in php, $ config ['enable _ Hooks'] = TRUE;). by adding a specific hook, the system can trigger a specific script at a specific time point:

$hook['post_system'] = array(    'class'     => 'frameLog',    'function'  => 'postLog',    'filename'  => 'post_system.php',    'filepath'   => 'hooks',);

The above Hook defines a post_system hook for script processing after the final page rendering (the parameter meaning can be referred to later or in the manual, and no more explanation is provided here ).

The problem arises:

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

Let's look at it step by step.

1. what is a hook?

Baidu Encyclopedia defines hooks as follows:

A hook is actually a program segment for message processing. it is called by the system and mounted to the system. When a specific message is sent, the hook program captures the message before it reaches the target window, that is, the hook function gets control of the message first. In this case, the hook function can process (change) the message, continue to transmit the message without processing it, and forcibly end the message transmission.

From the above definition, we can see the following points:

  1. Hook is an event-driven mode. its core is naturally an event (in CI, pre_system and pre_controller are all specific events ).
  2. Since it is event-driven, it must include the two most important steps: (1) event registration. For a Hook, it refers to the mounting of the Hook. (2) event triggering. Call a specific hook at a specific time point and execute the corresponding hook program.
  3. Since it is event-driven, it should also support multiple registration events of unified hook points.
  4. After the Hook is started, the process of the program may change, and there may be mutual calls between the hooks. if the Hook is not properly handled, there may be an endless loop. At the same time, Hook activation makes the program complex to a certain extent and difficult to debug.
2. pre-defined hooks in CI

Seven preset hook points are available in CI:

Pre_system:Refers to the hook before the system is loaded.

Pre_controller:The hook before the controller is called. the route and security check has been completed.

Post_controller_constructor:After the controller is instantiated, before any method is called

Post_controller:After the controller is fully running

Display_override:Rewrite 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 the Hook in CI is completed by the Hook component. First, let's look at the class diagram of this component:

Where:

Enabled: indicates whether the hook function is enabled.

Hooks: saves the list of enabled hooks in the system.

In_progress: we will see that this flag is used to prevent endless loops caused by mutual calls between hooks.

_ Construct is the constructor of the Hook component, in which _ initialize is called to complete initialization.

_ Call_hook: call _ run_hook to call the specified hook program. We have seen in CodeIgniter. php that _ call_hook is an interface actually provided to external calls.

_ Run_hook: the function used to actually execute the hook program

Before starting, we first paste the structure of the predefined hook. This structure may run throughout the source code, so we need to know the parameter meaning of this structure.

$ Hook ['XX'] = array ('class' => 'XX', // name of the class called by the hook, which can be blank 'function' => 'XX ', // the name of the function called by the hook is 'filename' => 'XX', // The file name of the hook is 'filepath' => 'XX ', // hook directory 'params' => 'XX' // parameters passed to the hook );

1) hook component initialization

The _ 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. you need to load the Config (Configuration Management component ):

1

2

3

4

5

6

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

If ($ CFG-> item ('enable _ Hooks') = FALSE)

{

Return;

}

(2) load the defined hook list

Similarly, you can set different ENVIRONMENT to enable different hooks. if so, the hooks under ENVRIONMENT are preferentially loaded:

1

2

3

4

5

6

7

8

If (defined ('enable') 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) Hook check. If no hook is set or the format of the hook is incorrect, exit without any processing:

1

2

3

4

If (! Isset ($ hook) OR! Is_array ($ hook ))

{

Return;

}

After initialize, Hook: hooks stores the defined hook list:

1

$ This-> hooks = & $ hook;

2. hook specified by Call

_ Call_hook is the interface directly called in the main program. The main work of this interface is:

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

1

2

3

4

If (! $ This-> enabled OR! Isset ($ this-> hooks [$ which])

{

Return FALSE;

}

(2) Check whether multiple hooks are enabled for the same hook point. if so, execute the following commands in sequence:

1

2

3

4

5

6

7

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 to execute it.

1

2

3

4

Else

{

$ This-> _ run_hook ($ this-> hooks [$ which]);

}

_ Run_hook is the function that actually executes the hook.

3. run the specific hook program.

The _ run_hook function is the actual executor of the hook. the Function receives a predefined hook array as a parameter and implements the following:

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

1

2

3

4

If (! Is_array ($ data ))

{

Return FALSE;

}

(2) Check the hook execution status.

In_progress indicates the execution status of the current hook. This parameter is mainly used to prevent endless loops caused by mutual calls between hooks.

1

2

3

4

If ($ this-> in_progress = TRUE)

{

Return;

}

(3) check the validity of the Hook.

For the sake of convenience, we propose a predefined hook parameter again:

$ Hook ['XX'] = array ('class' => 'XX', // name of the class called by the hook, which can be blank 'function' => 'XX ', // the name of the function called by the hook is 'filename' => 'XX', // The file name of the hook is 'filepath' => 'XX ', // hook directory 'params' => 'XX' // parameters passed to the hook );

Among them, class and params are optional parameters, and the other three parameters are required. If this parameter is not provided, the hook program cannot be accurately located and can only be returned directly:

1

2

3

4

5

6

7

8

9

10

11

If (! Isset ($ data ['filepath']) OR! Isset ($ data ['filename'])

{

Return FALSE;

}

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

If (! File_exists ($ filepath ))

{

Return FALSE;

}

(4). at this point, we have basically confirmed the location of the Hook program. There are two situations:

A. the class parameter in the predefined hook is null, indicating that a procedural call is used, and function xxx in the hook file is directly executed.

B. if the class parameter is not null and the object-oriented method is provided, the actual hook program is $ class-> $ function. similarly, if neither the class nor the function parameter is set, the hook cannot be executed and the following result is returned:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

$ Class = FALSE;

$ Function = FALSE;

$ Params = '';

/* Obtain the hook class */

If (isset ($ data ['class']) AND $ data ['class']! = '')

{

$ Class = $ data ['class'];

}

/* Obtain the hook function */

If (isset ($ data ['function'])

{

$ Function = $ data ['function'];

}

/* Get the passed hook parameter */

If (isset ($ data ['params'])

{

$ Params = $ data ['params '];

}

/* If neither class nor function exists, the hook program cannot be located and the hook program is directly returned */

If ($ class === false and $ function === FALSE)

{

Return FALSE;

}

(5). set the execution flag in_progress and execute the hook in the above two cases:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/* Object-oriented setting method */

If ($ class! = FALSE)

{

If (! Class_exists ($ class ))

{

Require ($ filepath );

}

$ HOOK = new $ class;

$ HOOK-> $ function ($ params );

}

/* Procedural execution method */

Else

{

If (! Function_exists ($ function ))

{

Require ($ filepath );

}

$ Function ($ params );

}

Finally, do not forget to set the in_progress flag to false after the hook is executed, and return the execution success flag:

1

2

$ This-> in_progress = FALSE;

Return TRUE;

Complete source code of the Hook component:

+ View Code

References

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

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

3. Layout implemented by http://codeigniter.org.cn/forums/thread-4947-1-1.html hooks

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.