- Learn a few things about PHP closures
- Chestnut 1 is used for callbacks
- Chestnut 2 is used for variable assignment
- Inherit variables from the parent scope
- The premise of chestnut 4 is simple to understand
call_user_func_array()
andcall_user_func()
methods- Call_user_func – The first argument is called as a callback function
- 2. Call_user_func_array – Calls the callback function and takes an array parameter to the callback function
- Bind closures to specified objects
- Closure::bindTo – Copies the current Closure object, binding the specified $this object to the class scope.
- 2. Closure:: Bind — Copy a Closure that binds the specified $this object to the class scope.
- Vi. Reference materials
If there is a harvest, please add a small star. If there is no harvest, you can oppose to report three even without help
- The sample code
- This paper addresses
- My ability is limited, if encounter what wrong place also hope to point out correction, thank you
- All chestnut outputs are used
symfony/var-dumpe
Beautify the
Anonymous functions, also known as closures, allow for the temporary creation of an unnamed function. It is most often used as the value of a callback argument. Of course, there are other applications as well.
Anonymous functions are currently implemented through the Closure class.
Chestnut 1 is used for callbacks
$rs = preg_replace_callback('/-([a-z])/'.function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
dump($rs); // "helloWorld"
Copy the code
Chestnut 2 is used for variable assignment
$greet = function ($name) {
dump($name);
};
dump($greet instanceof Closure); // true
$greet('PHP'); // "PHP"
Copy the code
Inherit variables from the parent scope
$message = 'hello';
$example = function (a) use ($message) {
dump($message);
};
dump($example instanceof Closure); // true
$example(); // "hello"
Copy the code
The premise of chestnut 4 is simple to understandcall_user_func_array()
andcall_user_func()
methods
Call_user_func – The first argument is called as a callback function
function call_user_func (parameter) {}
This method takes multiple arguments, the first of which is a callback function, which can be a normal function or a closure function, and the rest of which are used as function callbacks
$rs = call_user_func(function (... $params) {
return func_get_args();
}, 1.2.3);
dump($rs); / / [1, 2, 3]
Copy the code
2. Call_user_func_array – Calls the callback function and takes an array parameter to the callback function
function call_user_func_array (param_arr) {}
This method takes two arguments, the first of which is a callback function, which can be either a normal function or a closure function, and the array arguments that follow are used as function callbacks
$rs = call_user_func_array(function (array $params) {
returnfunc_get_args(); },1.2.3]);
dump($rs); / / [1, 2, 3]
Copy the code
Bind closures to specified objects
The idea is to bind a method to a specified class so that the method can also use properties and methods of the class. This works well with the __call() magic method and the call_user_func_array method
Closure::bindTo – Copies the current Closure object, binding the specified $this object to the class scope.
function bindTo(newscope = ‘static’) { }
namespace PHP\Demo\Closure;
class ClosureBindTo
{
public function __call($name, $arguments)
{
if (count($arguments) > 1 && $arguments[0] instanceof \Closure) {
return call_user_func_array($arguments[0]->bindTo($this), array_slice($arguments, 1));
}
throw new \InvalidArgumentException("There is no such thing."); }}/ / test
public function testClosureBindTo(a)
{
$obj = new ClosureBindTo();
$this->assertEquals(2, $obj->add(function (array $params) {
return ++$params[0]; },1]));
// Test the same instance
$newObj = $obj->test(function (array $params){
return $this; },1]);
$this->assertTrue($newObj instanceof $obj);
}
Copy the code
2. Closure:: Bind — Copy a Closure that binds the specified $this object to the class scope.
static function bind(Closure newthis, $newscope = ‘static’) { }
The bind function is a static representation of bindTo
namespace PHP\Demo\Closure;
class ClosureBind
{
private $methods = [];
public function addMethod(string $name, \Closure $callback)
{
if(! is_callable($callback)) {throw new \InvalidArgumentException("The second parameter is wrong.");
}
$this->methods[$name] = \Closure::bind($callback, $this, get_class());
}
public function __call(string $name, array $arguments)
{
if (isset($this->methods[$name])) {
return call_user_func_array($this->methods[$name], $arguments);
}
throw new \RuntimeException("[{$name}]"); }}/ / test
public function testClosureBind(a)
{
$obj = new ClosureBind();
$obj->addMethod('add'.function (array $params) {
return ++$params[0];
});
$this->assertEquals(2, $obj->add([1]));
// Test the same instance
$obj->addMethod('test'.function (array $params) {
return $this;
});
$this->assertTrue($obj->test([1]) instanceof $obj);
}
Copy the code
Vi. Reference materials
- The PHP manual