How do I implement a callback in PHP?
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.
How to use class methods as callbacks
Check the callable
manual to see all the different ways to pass a function as a callback. I copied that manual here and added some examples of each approach based on your scenario.
Callable
- A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo, empty(), eval(), exit(), isset(), list(), print or unset().
// Not applicable in your scenario
$this->processSomething('some_global_php_function');
- A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.
// Only from inside the same class
$this->processSomething([$this, 'myCallback']);
$this->processSomething([$this, 'myStaticCallback']);
// From either inside or outside the same class
$myObject->processSomething([new MyClass(), 'myCallback']);
$myObject->processSomething([new MyClass(), 'myStaticCallback']);
- Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0.
// Only from inside the same class
$this->processSomething([__CLASS__, 'myStaticCallback']);
// From either inside or outside the same class
$myObject->processSomething(['\Namespace\MyClass', 'myStaticCallback']);
$myObject->processSomething(['\Namespace\MyClass::myStaticCallback']); // PHP 5.2.3+
$myObject->processSomething([MyClass::class, 'myStaticCallback']); // PHP 5.5.0+
- Apart from common user-defined function, anonymous functions can also be passed to a callback parameter.
// Not applicable in your scenario unless you modify the structure
$this->processSomething(function() {
// process something directly here...
});
How to pass argument in callback function in php?
Use use
. :D
With the use
clause, you can import variables from the parent scope into the scope of the function.
public function GetOne($id){
$method = __METHOD__;
$post = null;
$post = $this->CacheManager($method, function() use ($id) {
return DB::select("select * from posts where id = ?", [$id]);
});
return $post;
}
Just a side note. Since it looks you are building a caching mechanism, you will need to include the ID in the cache as well. Currently you only check by $method
, but for each id you will probably have a different cache entry which may or may not exist. So I think in your function you need to do something like the line below to make the cache key more unique. I would also call the parameter $method
something like $cacheKey
instead, since to the cache it shouldn't be linked to a method name per se.
$method = __METHOD__ . ";$id";
Update for PHP 7.4: arrow functions
The RFC for arrow functions (AKA 'short closures') has passed voting.
With these you don't specify the parameters you want to close in, because they can only have a single expression anyway, so any expression/value they use can (and will) be taken from the parent function scope.
Since in this case the anonymous function just has a single statement, it can be rewritten into an arrow function. The call to the cache manager will then look like this:
public function GetOne($id){
$method = __METHOD__;
$post = null;
$post = $this->CacheManager($method, fn() => DB::select("select * from posts where id = ?", [$id]));
return $post;
}
pass a callback WITH arguments in PHP
$that = $this;
$wrapper = function() use($that) {
return $that->my_function_name('arg1', 'arg2');
};
What is a callback function and how do I use it with OOP
Here's a basic callback function example:
<?php
function thisFuncTakesACallback($callbackFunc)
{
echo "I'm going to call $callbackFunc!<br />";
$callbackFunc();
}
function thisFuncGetsCalled()
{
echo "I'm a callback function!<br />";
}
thisFuncTakesACallback( 'thisFuncGetsCalled' );
?>
You can call a function that has its name stored in a variable like this: $variable().
So, in the above example, we pass the name of the thisFuncGetsCalled function to thisFuncTakesACallback() which then calls the function passed in.
Related Topics
How to Read Last Lines (I.E. "Tail") from a File Using PHP
Using PHP'S Swiftmailer With Gmail
PHP Curl, Extract an Xml Response
How to Make Dot Match Newline Characters Using Regular Expressions
What Is the Function _Construct Used For
How to Overload Operators in PHP
Change Div Content Using Ajax, PHP and Jquery
What Does MySQL_Real_Escape_String() Do That Addslashes() Doesn'T
The Openssl Extension Is Required For Ssl/Tls Protection
How to Get Last Key in an Array
Yii2 Htaccess - How to Hide Frontend/Web and Backend/Web Completely
PHP - Setcookie(); Not Working
How to Best Store User Information and User Login and Password
Session Data Lost in Chrome Only
Path of Assets in CSS Files in Symfony 2