How are callbacks written in PHP?
- 
                    1Gonna link another [question](https://stackoverflow.com/questions/4535330/calling-closure-assigned-to-object-property-directly) to this one, because I was trying to call a closure. – akinuri Aug 28 '18 at 07:37
9 Answers
The manual uses the terms "callback" and "callable" interchangeably, however, "callback" traditionally refers to a string or array value that acts like a function pointer, referencing a function or class method for future invocation. This has allowed some elements of functional programming since PHP 4. The flavors are:
$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];
// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error
// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');
This is a safe way to use callable values in general:
if (is_callable($cb2)) {
    // Autoloading will be invoked to load the class "ClassName" if it's not
    // yet defined, and PHP will check that the class has a method
    // "someStaticMethod". Note that is_callable() will NOT verify that the
    // method can safely be executed in static context.
    $returnValue = call_user_func($cb2, $arg1, $arg2);
}
Modern PHP versions allow the first three formats above to be invoked directly as $cb(). call_user_func and call_user_func_array support all the above.
See: http://php.net/manual/en/language.types.callable.php
Notes/Caveats:
- If the function/class is namespaced, the string must contain the fully-qualified name. E.g. ['Vendor\Package\Foo', 'method']
- call_user_funcdoes not support passing non-objects by reference, so you can either use- call_user_func_arrayor, in later PHP versions, save the callback to a var and use the direct syntax:- $cb();
- Objects with an __invoke()method (including anonymous functions) fall under the category "callable" and can be used the same way, but I personally don't associate these with the legacy "callback" term.
- The legacy create_function()creates a global function and returns its name. It's a wrapper foreval()and anonymous functions should be used instead.
 
    
    - 8,671
- 2
- 42
- 48
- 
                    Indeed, using the function is the proper way to do it. While using a variable and then just calling it, as suggested in the accepted answer is cool, it's ugly and won't scale well with code. – icco Aug 30 '09 at 20:44
- 
                    4Changed accepted answer. Agreed with comments, this is a great answer. – Nick Stinemates Oct 05 '09 at 23:33
- 
                    It would be helpful to readers coming from Python programming to point out in the answer that `'someGlobalFunction'` indeed is a defined function. – TMOTTM Apr 02 '13 at 13:45
- 
                    1As of PHP 5.3, there are closures, see [Bart van Heukelom's answer](http://stackoverflow.com/a/2523807/1504300). It's much simpler and "standard" than all this legacy mess. – reallynice Apr 24 '15 at 15:53
- 
                    Yes, I mention anonymous functions in my answer, but the OP asked for "callback" (in 2008) and these older-style callbacks are still very much in use in tons of PHP codebases. – Steve Clay Apr 24 '15 at 19:53
With PHP 5.3, you can now do this:
function doIt($callback) { $callback(); }
doIt(function() {
    // this will be done
});
Finally a nice way to do it. A great addition to PHP, because callbacks are awesome.
 
    
    - 43,244
- 59
- 186
- 301
Implementation of a callback is done like so
// This function uses a callback function. 
function doIt($callback) 
{ 
    $data = "this is my data";
    $callback($data); 
} 
// This is a sample callback function for doIt(). 
function myCallback($data) 
{ 
    print 'Data is: ' .  $data .  "\n"; 
} 
// Call doIt() and pass our sample callback function's name. 
doIt('myCallback');
Displays: Data is: this is my data
 
    
    - 41,511
- 21
- 59
- 60
- 
                    23
- 
                    There are a few other ways to do it as shown above. I really thought the same. – Nick Stinemates Sep 08 '08 at 04:39
- 
                    
- 
                    3@Nick Retallack, I don't see what is so horrible about it. For the languages I know of, such as JavaScript and C#, they all can structure their callback function in such pattern. Coming from JavaScirpt and C#, I am really not used to call_user_func(). It makes me feel like I have to adapt myself to PHP, instead of the other way around. – Antony Dec 15 '11 at 14:16
- 
                    4@Antony I was objecting to the fact that strings are function pointers in this language. I posted that comment three years ago, so I'm pretty used to it by now, but I think PHP is the only language I know of (other than shell scripting) where this is the case. – Nick Retallack Dec 15 '11 at 19:00
- 
                    1@Antony I prefer to use the same syntax I use in javascript. So I don't even understand why people want to use `call_user_func()` When they have a syntax which enables them to dynamically call functions and make callbacks. I agree with you! – botenvouwer Aug 17 '13 at 12:25
One nifty trick that I've recently found is to use PHP's create_function() to create an anonymous/lambda function for one-shot use. It's useful for PHP functions like array_map(), preg_replace_callback(), or usort() that use callbacks for custom processing. It looks pretty much like it does an eval() under the covers, but it's still a nice functional-style way to use PHP.
 
    
    - 24,013
- 13
- 49
- 58
- 
                    6Unfortunately, the garbage collector doesn’t play very well with this construct producing potential memory leaks. If you’re out for performance, avoid create_function(). – fuxia Mar 26 '10 at 16:04
- 
                    Would you mind updating the answer with PHP 7.4 version (arrow functions) and adding a warning about deprecated `create_function()`? – Dharman Mar 01 '20 at 14:09
well... with 5.3 on the horizon, all will be better, because with 5.3, we'll get closures and with them anonymous functions
 
    
    - 12,548
- 5
- 34
- 31
You will want to verify whatever your calling is valid. For example, in the case of a specific function, you will want to check and see if the function exists:
function doIt($callback) {
    if(function_exists($callback)) {
        $callback();
    } else {
        // some error handling
    }
}
 
    
    - 17,368
- 20
- 81
- 90
- 
                    What if callback is not a function, but an array holding object and method? – d-_-b Apr 29 '10 at 11:59
- 
                    4
- 
                    1Both are good suggestions - It will be necessary to check your own particular implementation of how you do a callback. I was hoping to warn against calling something that didn't exist causing a fatal. I made the answer more general – SeanDowney Apr 03 '17 at 18:45
create_function did not work for me inside a class. I had to use call_user_func.
<?php
class Dispatcher {
    //Added explicit callback declaration.
    var $callback;
    public function Dispatcher( $callback ){
         $this->callback = $callback;
    }
    public function asynchronous_method(){
       //do asynch stuff, like fwrite...then, fire callback.
       if ( isset( $this->callback ) ) {
            if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
        }
    }
}
Then, to use:
<?php 
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
   print 'Data is: ' .  $data .  "\n";
}
?>
[Edit] Added a missing parenthesis. Also, added the callback declaration, I prefer it that way.
 
    
    - 2,183
- 16
- 29
- 
                    1Doesn't the Dispatcher class require an attribute for $this->callback = $callback to work? – James P. Sep 13 '11 at 01:02
- 
                    @james poulson: PHP is a dynamic language, so it works. But I was being lazy. I usually do declare properties, makes everyones life easier. Your question made me look at that code again and spot a syntax error, thou. Thanks – goliatone Sep 13 '11 at 09:28
- 
                    
- 
                    Woudn't it be safer to declare the do_callback function before creating the Dispatcher object and calling the async method? – ejectamenta Jan 08 '16 at 19:21
For those who don't care about breaking compatibility with PHP < 5.4, I'd suggest using type hinting to make a cleaner implementation.
function call_with_hello_and_append_world( callable $callback )
{
     // No need to check $closure because of the type hint
     return $callback( "hello" )."world";
}
function append_space( $string )
{
     return $string." ";
}
$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"
$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"
$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"
 
    
    - 43,213
- 17
- 66
- 89
- 
                    1**Warning** `create_function()` has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged. – Dharman Mar 01 '20 at 14:12
I cringe every time I use create_function() in php. 
Parameters are a coma separated string, the whole function body in a string... Argh... I think they could not have made it uglier even if they tried.
Unfortunately, it is the only choice when creating a named function is not worth the trouble.
 
    
    - 36,282
- 18
- 72
- 87
- 
                    1And, of course, it's runtime string eval, so it doesn't get checked for valid syntax or anything else at compile time. – hobbs Aug 13 '09 at 14:54
- 
                    This answer has been outdated for the past 2 years. `create_function()` is now deprecated and should not be used. – Dharman Mar 01 '20 at 14:11