Using Callback Functions in PHP
A commonly used technique when programming is to use callbacks. A callback is a piece of code that is passed to a function that is later executed by that function. In this article I will show you how to define and call callbacks in PHP, as well as a practical example of how callbacks can be useful.To demonstrate how callbacks can be beneficial, assume we have a PHP script that when called will download an RSS feed from 10 different web sites. If it takes 2 seconds to download from each site, it will take 20 seconds to download from all sites.
The code to achieve this may look something like the following code. I've added a called to sleep() to demonstrate how slow this script may be.
Listing 1 listing-1.php
// this function simulates downloading data from a site function downloadFromSites($sites) { $ret = array(); foreach ($sites as $site) { sleep(2); // write the data for this site to return array $ret[] = array( 'site' => $site, 'data' => 'downloaded data here' ); } return $ret; } // imaginary list of sites to download from $sites = array( 'http://www.example1.com', 'http://www.example2.com' // more sites... ); // start downloading and store the return data $data = downloadFromSites($sites); // output the return data foreach ($data as $row) { echo sprintf("Finished downloading from %s\n", $row['site']); }
A far better solution would be to return newly-downloaded data as it becomes available. Of course, you could hard-code the required functionality in the
downloadFromSites() function, but
doing so makes it extremely difficult to reuse the code and use the
returned data in a different way should the need arise.The following diagram shows the workflow of the previous function modified to use callbacks. In this case, the callback function is called every time a single site has completed downloading.
PHP makes using callbacks extremely simple using the helper functions is_callable() and call_user_func(). There are three types of callbacks that can be used:
- A standard PHP function. This is passed as a string such as
'callbackName' - A static method of a class. This is passed as an array with the
the class name as the first element and the method name as the second
argument. For example,
array('MyClass', 'MyCallback') - A method of an object. This is also passed as an array, but
instead of the class name being the first element, the object is. For
example,
array($obj, 'MyCallback')
Listing 2 listing-2.php
// Callback type 1: normal function function myCallback() { } $callback = 'myCallback'; // Callback type 2: static method class MyClass { public static function MyCallback() { } } $callback = array('MyClass', 'MyCallback'); // Callback type 3: object method class AnotherClass { public function MyCallback() { } } $obj = new AnotherClass(); $callback = array($obj, 'MyCallback');
Note: The static method callback is defined as
To test if a callback can be used you can use the is_callable()
function. This function accepts the callback as its only argument and
returns true if it's a valid callback. You can then call the callback
using call_user_func().
The callback is passed as the first argument, and if your callback
accepts any arguments you can include them as the second and subsequent
arguments.static.The following code demonstrates how this would be typically used. This code ensures a callback can be called, then calls it with a single argument. This script outputs
Hello.
Listing 3 listing-3.php
function myCallback($arg1) { echo $arg1; } $callback = 'myCallback'; if (is_callable($callback)) { call_user_func($callback, 'Hello'); }
Note: In this particular example you could simply call
Returning to our previous example, we can now alter the $callback('Hello').
The problem with this is that it will only work for normal
functions - you can't use a class method as a callback using this
technique.downloadFromSites()
function so it accepts a callback as the second argument. Now in
addition to returning all of the data once all sites have been
processed, the callback will be called after each site is processed.The callback will accept the site name as its first argument and the downloaded data as the second argument.
Listing 4 listing-4.php
// this function simulates downloading data from a site function downloadFromSites($sites, $callback = null) { $ret = array(); foreach ($sites as $site) { sleep(2); $data = 'downloaded data here'; // check if the callback is valid if (is_callable($callback)) { // callback is valid - call it with given arguments call_user_func($callback, $site, $data); } // write the data for this site to return array $ret[] = array( 'site' => $site, 'data' => $data ); } return $ret; } // define a fictional class used for the callback class MyClass { // this is the callback method public static function downloadComplete($site, $data) { echo sprintf("Finished downloading from %s\n", $site); } } // imaginary list of sites to download from $sites = array( 'http://www.example1.com', 'http://www.example2.com' // more sites... ); // start downloading and store the return data downloadFromSites($sites, array('MyClass', 'downloadComplete')); // we don't need to loop over the return data // now since the callback handles that instead
Further Reading
- PHP manual entry on callbacks
- PHP Manual: is_callable()
- PHP Manual: call_user_func()
- PHP Manual: call_user_func_array()
Other Options
- Download a PDF version of this article
- Put your PHP knowledge to the test with our online and iPad/iPhone quizzes
- View or post comments for this article
- Browse similar articles by tag: PHP
No comments:
Post a Comment