PHP Callback Functions – Simple Examples

Welcome to a quick tutorial and examples of PHP callback functions. Functions are one of the most basic things that we learn in PHP, then come along with this “callback function” thing… So, just what is a callback?

In simple terms, a callback function is:

  1. A function that is passed into another function as a parameter.
  2. The function is then called inside the other function itself.

Yes, that’s all. Callbacks are actually simple, but yet confusing at the same time. Let us walk through some examples in this guide – Read on!

ⓘ I have included a zip file with all the example 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.

 

 

REAL QUICK SLIDES

 

TABLE OF CONTENTS

Download & Notes Callback Examples Useful Bits & Links
The End

 

DOWNLOAD & NOTES

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

 

EXAMPLE CODE DOWNLOAD

Click here to download the example 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.

 

QUICK NOTES

If you spot a bug, please feel free to comment below. I try to answer 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.

 

 

CALLBACK FUNCTION EXAMPLES

All right, let us now get into the examples on PHP callback functions.

 

1) CLASSIC CALLBACK FUNCTION EXAMPLE

1-classic.php
<?php
// (A) FUNCTION TO CALLBACK
function myFunkyFunc () {
  echo "FOO!";
}

// (B) PASS MYFUNKYFUNC INTO CALL_USER_FUNC()
call_user_func("myFunkyFunc");

First, we have a very simple and classic example here. Remember the two “conditions” of what makes a callback function?

  • Pass a function as a parameter into another function – We have function myFunkyFunc() here, which is passed into call_user_func() as a parameter.
  • Callback function gets called inside the function itself – call_user_func() will call myFunkyFunc().

For you guys who have not figured out where the name “callback” comes from – myFunkyFunc() is passed into call_user_func(), then call_user_func() calls back to myFunkyFunc(). Get it?

 

 

2) ANOTHER SIMPLE EXAMPLE

2-simple.php
// (A) FUNCTIONS TO CALL BACK
function myFunkyA () {
  echo "FOO!";
}
function myFunkyB () {
  echo "BAR!";
}
 
// (B) THE "MAIN" FUNCTION
function notFunky ($callMeBack) {
  echo "Not Funky - ";
  if (is_callable($callMeBack)) { $callMeBack(); }
  echo "<br>";
}
 
// (C) PASS CALLBACK FUNCTIONS INTO "MAIN FUNCTION"
notFunky("myFunkyA");
notFunky("myFunkyB");

Let us take “very simple” up a notch to “simple”. This is pretty much how a “common callback” will look like.

  • We have a “main” notFunky() function that will call back to $callMeBack if specified.
  • So, very straightforward – notFunky("myFunkyA") will call back to myFunkyA(), and notFunky("myFunkyB") will call back to myFunkyB().

As to why we do this “dumb” way of passing a function into a function, see the following examples.

 

 

3) PASS PARAMETERS TO CALLBACK FUNCTION

3-parameters.php
<?php
// (A) "MAIN" FUNCTION - DOES A CURL CALL TO FETCH A WEBSITE
function curlFetch ($url, $after) {
  // (A1) FETCH CONTENT FROM URL
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($ch);
 
  // (A2) CALLBACK AFTER CURL FETCH
  if (is_callable($after)) { $after($result); }
}
 
// (B) CALLBACK FUNCTIONS
// (B1) DIRECT OUTPUT
function output ($result) {
  echo $result;
}
curlFetch("http://localhost/README.txt", "output");
 
// (B2) SAVE TO FILE
function saveFile ($result) {
  file_put_contents("test.html", $result);
  echo "Saved to file!";
}
curlFetch("https://en.wikipedia.org/wiki/Portal:Solar_System", "saveFile");

Here is an actually useful example.

  • The “main” function curlFetch() will use CURL to fetch content from a website.
  • The fetched content will then be passed into the callback function – $after($result).
  • When we pass output() into curlFetch(), it results in the content being directly output – echo $result.
  • But when we pass saveFile() into curlFetch(), it results in the content being saved into a file – file_put_contents("test.html", $result).

This is one of the powers of callbacks. It allows us to fluidly reuse a function, do various different things depending on which callback that we pass in.

 

 

4) WHY USE CALLBACKS?

Some of you smart code ninjas should have spotted the hiccup. We can actually do the above example in a sequential manner:

$result = curlFetch("WEBSITE-A");
output($result);
$result = curlFetch("WEBSITE-B");
saveFile($result);

Isn’t this better and less confusing? Why the dumb and roundabout way of passing a function into a function? To answer that question, let’s not do “sequential fetch one-by-one”, but “fetch asynchronously all-at-once”.

4-why-callback.php
<?php
// (A) CALLBACK FUNCTIONS
// (A1) DIRECT OUTPUT
function output ($result) { echo $result; }
 
// (A2) SAVE TO FILE
function saveFile ($result) {
  file_put_contents("test.html", $result);
  echo "Saved to file!";
}

// (B) ASYNCHRONOUS FETCH MULTIPLE WEBSITES
function fetch ($list) {
  // (B1) MULTI-CURL INIT
  $mh = curl_multi_init();
  $multi = []; $i = 0;
  foreach ($list as $url=>$callback) {
    $multi[$i] = curl_init();
    curl_setopt($multi[$i], CURLOPT_URL, $url);
    curl_setopt($multi[$i], CURLOPT_HEADER, 0);
    curl_setopt($multi[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($mh, $multi[$i]);
    $i++;
  }

  // (B2) CURL EXEC
  do {
    // GET CURL EXEC STATUS
    $status = curl_multi_exec($mh, $active);
    
    // CREDITS: https://gist.github.com/Xeoncross/2362936
    // WHEN A CURL REQUEST IS COMPLETE - RUN CALLBACK
    if ($state = curl_multi_info_read($mh)) {
      $info = curl_getinfo($state['handle']);
      $callback = $list[$info['url']];
		  $callback(curl_multi_getcontent($state['handle']), $info);
      curl_multi_remove_handle($mh, $state['handle']);
    }
    
    // SHORT PAUSE TO NOT FLOOD CPU
    usleep(10000);
  } while ($status == CURLM_CALL_MULTI_PERFORM || $active);
  
  // (B3) CASE CLOSED - ALL DONE
  curl_multi_close($mh);
}
 
// (C) GO!
fetch([
  "http://localhost/README.txt" => "output",
  "https://en.wikipedia.org/wiki/Portal:Solar_System" => "saveFile"
]);

This might be a little brutal for beginners, but let’s put it in simple terms – Some websites are faster, some are slower. When it comes to multiple fetching and processing in parallel, we do not know which one will end first.

This is where callbacks make sense – Whichever “fetch website” finishes first will run their respective callback function first; This saves time and offers better performance when compared to “one-by-one.”

 

 

5) CALLBACK FUNCTION IN CLASS

5-class-callback.php
<?php
// (A) CLASS - STATIC FUNCTION TO CALLBACK
class MyClass {
  public static function MyFunc () {
    echo "FOO!";
  }
}
 
// (B) THE "MAIN" FUNCTION
function funky ($callMeBack) {
  if (is_callable($callMeBack)) { $callMeBack(); }
}
 
// (C) PASS STATIC FUNCTION MYFUNC() INTO FUNKY()
funky("MyClass::MyFunc");

Yep, it’s that simple – CLASS::FUNCTION if you ever need to callback a function in a class. But take note that the callback function must be static or PHP will throw an error.

 

6) CALLBACK FUNCTION IN OBJECT

6-object-callback.php
<?php
// (A) OBJECT - TO CALLBACK MYFUNC()
class MyClass {
  public function MyFunc () {
    echo "FOO!";
  }
}
$myObj = new MyClass();
 
// (B) THE "MAIN" FUNCTION
function funky ($callMeBack) {
  // (B1) FUNCTION IN OBJECT
  if (is_array($callMeBack)) { call_user_func($callMeBack); }
 
  // (B2) "REGULAR" CALLBACK FUNCTIONS
  else if (is_callable($callMeBack)) { $callMeBack(); }
}
 
// (C) PASS OBJECT + FUNCTION TO CALL
// SINCE OBJECTS ARE NOT GLOBAL, WE HAVE TO PASS IN ENTIRE OBJECT
funky([$myObj, "MyFunc"]);

Finally, the complication comes when calling a function in an object. Since objects are not global, we have to pass in the entire object along with the callback function.

 

USEFUL BITS & LINKS

That’s all for the code, and here are some small extras that may be useful to you.

 

INFOGRAPHIC CHEAT SHEET

Callback Functions In PHP (Click to enlarge)

 

LINKS & REFERENCES

 

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 callback functions, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “PHP Callback Functions – Simple Examples”

  1. Hello
    to better understand
    give exactly the example “2) ANOTHER SIMPLE EXAMPLE” but more simply the entire tutorial and then back specifically to example #2

    Why you need or you go for that callback instead of a function where you just pass the string to echo as parameter?

    I would kindly suggest to begin the tutorial with a sort of introduction to the problem that WITHOUT a call back you can’t solve OR how much code you can cut with callbacks .

    Thank you if you can teach here in the comments or implement it in the tutorial

    1. EDIT: OK, I think I catch what you mean. Example 3 – The sequential manner works too:

      $content = curlFetch("http://site.com");
      output($content);
      saveFile($content);

      Good point – Why the need for callback then? What good are callbacks for? Tutorial slightly updated. See 3 & 4 above.

Leave a Comment

Your email address will not be published. Required fields are marked *