How To Create Hooks In PHP (Simple Examples)

Welcome to a tutorial on how to create hooks in PHP. So you may be wondering how hooks work in PHP after using them in WordPress, Drupal, Codeigniter, or in other programming languages. Well, for a quick answer:

Hooks are mechanics that are commonly used to change or complete a process. However, hooks are not natively implemented in PHP – We can only simulate hooks in PHP by using functions or loading external scripts.

Let us walk through a few examples to better illustrate this – Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

QUICK SLIDES

 

TABLE OF CONTENTS

Download & Notes Hook Basics Hook Examples
Useful Bits & Links The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

HOOK BASICS

Before we go into the code examples, let us start by answering the basic questions – What the heck is a hook, what does it do, and why do we need them? Feel free to skip these if you are already a code ninja.

 

WHAT IS A HOOK?

In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components.

Wikipedia

Several other geeky websites also offer a similar answer. Just what does this mean? Maybe a practical example will illustrate hooks better. Let’s say that we have a saveUser() function that saves a new user into the database.

That should be straightforward enough, but here comes the twist – What if we want to check the input before processing the save? What if we want to send an email after a successful save?

This is where we can use hooks to “intercept” the input for checks before the saving starts and intercept after the save to send out an email.

 

WHY USE HOOKS?

The smart alecks should be thinking – This is so stupid. Just change saveUser() directly to do the checks and send the email. Nobody ain’t got time for hooks. Yes, we can do that, but consider the case of an international company.

It will make more sense to keep saveUser() as a pure “save-to-database” function – The checks are different for every region, with different locale settings and rules. Some countries may also have a different “post-process”, apart from sending out a “welcome” email.

This is the basic idea of hooks. We leave the “core function” untouched, but use hooks to extend the usability and/or change the entire process.

 

 

HOOKS VS CALLBACK VS EVENTS

At this stage, some of you advanced code ninjas should be thinking that hooks are something like events and callbacks. Yes, they are close relatives, but not the same.

  • Events are fired when something happens.
  • A callback is a function that is passed into another function.
  • Hooks are interceptors. They can interrupt and change the way a process works.

 

EXAMPLES OF HOOKS IN PHP

Sadly, hooks are not natively implemented in PHP. We can only use various mechanics to simulate “hook-like” implementations in PHP, here are a few common examples.

 

EXAMPLE 1) HOOKS USING FUNCTIONS

1-function.php
<?php
// (A) SAVE USER FUNCTION
$error = ""; // ERROR MESSAGE
function save ($name, $email) {
  // (A1) BEFORE HOOK
  $pass = true;
  if (function_exists("before")) { $pass = before($name, $email); }

  // (A2) SAVE USER - THIS EXAMPLE SAVES TO A DUMMY FILE
  if ($pass) { if (file_put_contents("user.txt", "$name\r\n$email") === false) {
    $GLOBALS["error"] = "Error writing to file.";
    $pass = false;
  }}

  // (A3) AFTER HOOK
  if ($pass && function_exists("after")) { $pass = after($name, $email); }

  // (A4) RESULT
  return $pass;
}

// (B) THE HOOKS
// (B1) BEFORE SAVE - CHECK USER
function before ($name, $email) {
  // NAME MUST BE AT LEAST 2 CHARACTERS
  if (strlen($name) < 2) { 
    $GLOBALS["error"] = "Name must be at least 2 characters";
    return false; 
  }

  // VALID EMAIL
  if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $GLOBALS["error"] = "Invalid email";
    return false;
  }

  return true;
}

// (B2) AFTER SAVE - SEND EMAIL
function after ($name, $email) {
  if (!mail($email, "Welcome", "Welcome to Test Co.")) {
    $GLOBALS["error"] = "Failed to send email to $email";
    return false;
  }
  return true;
}

// (C) GO!
echo save ("Jon Doe", "jon@doe.com") ? "OK" : $error ;

Yep, this is pretty much a “detailed version” of the above “save user” example. How we simulate hooks here is pretty simple – Notice how we use if (function_exists(FUNCTION)) { FUNCTION(); } here? This is one of the common ways hooks are simulated in PHP, by running functions if they exist.

 

 

EXAMPLE 2) HOOKS WITH CALLBACK FUNCTIONS

2-callback.php
<?php
// (A) SAVE USER FUNCTION
$error = ""; // ERROR MESSAGE
function save ($name, $email, $before=null, $after=null) {
  // (A1) BEFORE HOOK
  $pass = true;
  if ($before!=null) { $pass = $before($name, $email); }

  // (A2) SAVE USER
  if ($pass) { if (file_put_contents("user.txt", "$name\r\n$email") === false) {
    $GLOBALS["error"] = "Error writing to file.";
    $pass = false;
  }}

  // (A3) AFTER HOOK
  if ($after!=null) { $pass = $after($name, $email); }

  // (A4) RESULT
  return $pass;
}

// (B) GO!
echo save (
  // (B1) NAME & EMAIL
  "Jon Doe", "jon@doe.com",
 
  // (B2) BEFORE
  function ($name, $email) {
    // NAME MUST BE AT LEAST 2 CHARACTERS
    if (strlen($name) < 2) { 
      $GLOBALS["error"] = "Name must be at least 2 characters";
      return false; 
    }

    // VALID EMAIL
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $GLOBALS["error"] = "Invalid email";
      return false;
    }

    return true;
  },

  // (B3) AFTER
  function ($name, $email) {
    if (!mail($email, "Welcome", "Welcome to Test Co.")) {
      $GLOBALS["error"] = "Failed to send email to $email";
      return false;
    }
    return true;
  }
) ? "OK" : $error ;

Notice how we pass the “before” and “after” functions in? I know, some of the hater flamer trolls are going to say “these are just callback functions”. Yes, they are – Remember that we don’t have native hooks in PHP? This is “an alternative”, not an actual hook.

 

 

EXAMPLE 3) HOOKS USING EXTERNAL SCRIPTS

3a-load.php
<?php
// (A) SAVE USER FUNCTION
$error = ""; // ERROR MESSAGE
function save ($name, $email, $before="", $after="") {
  // (A1) BEFORE HOOK
  $pass = true;
  if ($before!="" && file_exists($before)) { include $before; }

  // (A2) SAVE USER
  if ($pass) {if (file_put_contents("user.txt", "$name\r\n$email") === false) {
    $GLOBALS["error"] = "Error writing to file.";
    $pass = false;
  }}

  // (A3) AFTER HOOK
  if ($after!="" && file_exists($after)) { include $after; }

  // (A4) RESULT
  return $pass;
}

// (B) GO
echo save ("Jon Doe", "jon@doe.com", "3b-before.php", "3c-after.php")
  ? "OK" : $error ;
3b-before.php
<?php
// NAME MUST BE AT LEAST 2 CHARACTERS
if (strlen($name) < 2) { 
  $GLOBALS["error"] = "Name must be at least 2 characters";
  $pass = false;
}

// VALID EMAIL
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
  $GLOBALS["error"] = "Invalid email";
  $pass = false;
}
3c-after.php
<?php 
if (!mail($email, "Welcome", "Welcome to Test Co.")) {
  $GLOBALS["error"] = "Failed to send email to $email";
  $pass = false;
}

This final alternative is a rare one – We specify the hooks in separate scripts.

 

 

USEFUL BITS & LINKS

That’s all for the code, and here are a few extras that may be useful.

 

WHICH IS THE BEST?

All of the above methods are possible solutions, and whichever works best for your project is the best method. But personally, I am leaning towards global functions and callbacks – That is how most of the frameworks and packages work too.

 

INFOGRAPHIC CHEAT SHEET

Hooks In PHP (Click To Enlarge)

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better understand hooks, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

1 thought on “How To Create Hooks In PHP (Simple Examples)”

Leave a Comment

Your email address will not be published.