As a CodeIgniter developer, sometimes you end up in a situation that requires you to alter the core of the framework or the execution flow to fulfill your custom requirements. Of course, it's never recommended to modify the core files as it makes the upgrade process cumbersome. Luckily, the CodeIgniter framework comes with the hooks system, which allows you deal with this scenario.
In this article, we'll start with an introduction to the hooks system in the CodeIgniter framework. Then, we'll discuss the different types of hooks available. And finally, we'll grab this opportunity to explore the creation of custom hooks.
Hooks: A System to Override the Core Framework
Let's have a quick look at what the official CodeIgniter documentation says about the hooks system:
CodeIgniter’s Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files.
Sounds pretty self-explanatory, doesn't it? In your day-to-day application development, if you ever find yourself tempted to modify the core CodeIgniter files, you should first consider the hooks system to see if it fulfills your requirements.
Let's assume that you want to build a custom performance benchmark system to monitor the application execution. You realize that the core files need to be modified in order to achieve the desired output. In that case, you could use the pre_system
and the post_system
hooks to get into the execution flow and collect the statistics as needed.
If you're aware of the event observer pattern, the concept is similar in that you listen for the system generated events, and the corresponding observer code gets executed when the observed event is triggered.
So that was a basic introduction to the hooks system in CodeIgniter. In the next section, we'll have a close look at the different hooks available for you to plug into the system.
Go Through the Different Hooks
The CodeIgniter hook system provides different hook points that you can use while implementing your custom hooks. The hook point is basically a certain state in the request execution workflow at a given time.
For example, when you implement the pre_system
hook, you know that you’re at the very beginning of the bootstrapping phase. On the other hand, if you’ve chosen the post_system
hook, you can be sure that the execution is completed and the response is already sent to the client.
In this section, we’ll go through the different hook points that are provisioned by the CodeIgniter hook system.
System Hooks
The pre_system
and the post_system
hooks fall under this category as the former one is called very early during the bootstrapping phase while the latter one is called after the page execution is completed.
I can think of a few use cases that could be achieved with system hooks:
- Benchmark
- Logging
- Rule-based redirection
- And more
Controller Hooks
There are three hooks that fall under this category, so let's go through each of them.
Pre Controller Hook
The pre_controller
hook is called just prior to the controller class being instantiated. So, if you would like to do any further checks before the controller gets called, this is the hook you're looking for.
Post Controller Constructor Hook
As the name suggests, the post_controller_constructor
hook is called immediately after the controller object is instantiated and prior to the actual method call.
At this point, you're sure that the controller is instantiated and the method is going to be called soon, so you could load any controller specific libraries here, or you could implement the controller-specific custom validation as well.
Post Controller Hook
The post_controller
hook is called after the execution of the controller method. So the stuff that you want to execute after execution of the controller should be implemented with this hook.
So that was the story of the controller specific hooks.
Overrides Hooks
Display Override Hook
According to the CodeIgniter documentation, the display_override
hook overrides the core _display
method. The core _display
method is used to send the output to the client, and thus by using the display_override
hook you could alter the way the output is sent to the user.
In fact, we'll explore this hook in detail as we move on to the next section, in which we'll discuss how to create a custom hook.
Cache Override Hook
The cache_override
hook overrides the core _display_cache
method of the Output
class. The _display_cache
method is responsible for serving the cached output, so you could use this hook should you wish to serve the page output from the different cached location just in case you've implemented a different caching mechanism.
That ends the story of different hook points in the CodeIgniter hook system. In the next section, we'll see how exactly you could take an advantage of the hook system by implementing a real-world example.
How to Create a Custom Hook
I'm sure that you've had enough theory so far, so let's get back to some practical development! In this section, we'll create a custom hook to demonstrate the concepts discussed so far in this article.
In our case, we'll use the display_override
hook that'll be responsible for the token replacement. To be more precise, we'll replace all the occurrences of [DATETIME]
with the current date. Of course, that sounds like a pretty simple use case, but you could easily extend it to be more specific as per your requirements.
By default, the hook system is disabled in the core framework, so the first thing you need to do is to enable the hook system.
Go ahead and open the configuration file application/config/config.php
.
Look for the following snippet and turn it on by changing FALSE
to TRUE
.
<?php /* |-------------------------------------------------------------------------- | Enable/Disable System Hooks |-------------------------------------------------------------------------- | | If you would like to use the 'hooks' feature you must enable it by | setting this variable to TRUE (boolean). See the user guide for details. | */ $config['enable_hooks'] = FALSE;
Now, we're ready to define our hooks. In fact, CodeIgniter already comes with the file application/config/hooks.php
that you could use should you wish to define hooks.
By default, the hooks.php
file is empty, so let's add our custom hook code to make it more meaningful.
<?php defined('BASEPATH') OR exit('No direct script access allowed'); $hook['display_override'] = array( 'class' => 'ReplaceToken', 'function' => 'replacePlaceholderCode', 'filename' => 'ReplaceToken.php', 'filepath' => 'hooks' );
The syntax of defining a custom hook is pretty simple. It's the $hook
array that holds all the hooks that need to be executed.
The key of each array entry is the name of the hook itself you're defining. When you're defining a hook, you're telling the system to execute a certain piece of code when something happens. That's exactly what needs to be supplied as a value of any hook. Let's go through each key quickly.
- The
class
key holds the name of a class that holds the code that needs to be executed. - The
function
key holds the name of the method that'll be called upon the hook execution. - The
filename
key points to the file that defines the complete hook code. - The
filepath
defines the directory path of the file declared under thefilename
key, and it's relative to theapplication
directory. Generally, it's set tohooks
, thus resulting in anapplication/hooks
structure. Of course, there's nothing stopping you from defining a completely different path if you wish to do so.
As a side note, if you don't want to create a class file, you could also supply a closure function that'll be executed when the hook is triggered.
In our case, we'll create a file ReplaceToken.php
and according to the hook definition it must be placed under the application/hooks
directory.
Go ahead and create a file application/hooks/ReplaceToken.php
with the following contents.
<?php class ReplaceToken { public function replacePlaceholderCode() { // load the instance $this->CI =& get_instance(); // get the actual output $contents = $this->CI->output->get_output(); // replace the tokens $this->CI->load->helper('date'); $contents = str_replace("[DATETIME]", standard_date(), $contents); // set the output echo $contents; return; } }
The object of our hook is to replace the [DATETIME]
placeholder with the actual date before the output of any page in our application is sent to the client.
As we've discussed earlier, the output of the page is already built by the time the display_override
hook is called. So the first thing that we would like to do is to fetch the output that's ready to be sent to the user.
// load the instance $this->CI =& get_instance(); // get the actual output $contents = $this->CI->output->get_output();
The get_instance
method is used to instantiate the application instance, and it's assigned to $this->CI
. Next, we use the get_output
method of the Output
class to fetch the response contents.
The rest is pretty simple. The [DATETIME]
placeholder needs to be replaced with the actual date. To make things easier, the date
helper is used to carry out the desired operation, and we're almost done as far as our hook logic is concerned.
// replace the tokens $this->CI->load->helper('date'); $contents = str_replace("[DATETIME]", standard_date(), $contents);
Finally, you need to echo the output as the display_override
overrides the _display
method that is used to send the output to the client. So we need to do it ourselves in this case; otherwise, it would have been handled by the core _display
method.
// set the output echo $contents; return;
In fact, that ends the story of our custom hook!
Now, let's go ahead and make a new CodeIgniter page so that we can test our custom hook. Create a controller file application/controllers/TokenExample.php
with the following contents.
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class TokenExample extends CI_Controller { public function index() { $this->load->view('token_content'); } }
And here's how the associated view file application/views/token_content.php
should look.
Today's date: [DATETIME]
And that's pretty much it. Point your browser to http://your-code-igniter-site-url/TokenExample/index and you should see the expected output!
So that's the hook system at your disposal should you wish to get into the typical workflow of the CodeIgniter application. I hope that you've enjoyed the article and that it helps you in your day-to-day CodeIgniter application development.
Conclusion
Today, we went through one of the exciting built-in CodeIgniter feature—hooks. Hooks allow you to intervene in the typical request execution workflow of your CodeIgniter application.
At the beginning of the article, we discussed the basic concept of Hooks in CodeIgniter, and then we discussed the different hooks available in the system. Finally, in the last section we explored how to create a custom hook and its inner workings.
Don't hesitate to express your thoughts using the feed below. Also, if you want me to come up with any specific topics, please just let me know.
No comments:
Post a Comment