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_func
does not support passing non-objects by reference, so you can either usecall_user_func_array
or, 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