• 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 understandcall_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 usedsymfony/var-dumpeBeautify 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