Friday, August 25, 2017

How CodeIgniter's Hook System Works

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.

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.

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 the filename key, and it's relative to the application directory. Generally, it's set to hooks, thus resulting in an application/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.

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.

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.

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.

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.

And here's how the associated view file application/views/token_content.php should look.

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.


by Sajal Soni via Envato Tuts+ Code

No comments:

Post a Comment