简体   繁体   English

将类方法传递给PHP中的闭包(类似于JS)

[英]Pass class method to a closure in PHP (similar to JS)

In Javascript you can do this: 在Javascript中,您可以执行以下操作:

// Define a function
function logIt(a, b) { console.log(a, b); }

function somethingElse() {
    // Store it in a variable
    var theLog = logIt; 
    // Call it somewhere else *as the variable-name*
    asyncCall(function() { theLog(1, 2); });
}

What I'd like to do in PHP is this: 我想在PHP中做的是这样的:

class A
{
    // Define a simple class method
    protected function echoIt($a, $b) {
        echo $a, $b;
    }

    public function doSomething(array $things) {
        $theEchoFunction = $this->echoIt; // save it for the next line

        // Get into a closure and pass the method as a variable
        array_map(function($thing) use ($theEchoFunction) { // <-- this is the bit I'd like to do
            // Call the function directly from the variable
            $theEchoFunction($thing[0], $thing[1]);
        }, $things);
    }
}

I know that it's easy enough to just do $that = $this; 我知道做$that = $this;很简单$that = $this; then pass $that through to the closure, but that means I can't access $that->echoIt because it's protected. 然后将$that传递给闭包,但这意味着我无法访问$that->echoIt因为它受到了保护。 Is it possible to send the method itself to the closure? 是否可以将方法本身发送给闭包?

This question could actually be the X/Y problem I guess. 我猜这个问题实际上可能是X / Y问题 What I want to do is call the protected method from inside the closure. 我想做的是从闭包内部调用受保护的方法。 I'd like to just pass the method so that the closure doesn't need to know that the class has an echoIt method. 我只想传递该方法,以便闭包不需要知道该类具有echoIt方法。

Specifically, this will do just fine* (in PHP as in Javascript): 具体来说,这可以很好地完成*(在PHP和Javascript中):

class A
{

    protected function echoIt($a, $b) {
        echo $a, $b;
    }

    public function doSomething(array $things) {
        array_map(function ($thing) {
            $this->echoIt($thing[0], $thing[1]);
        }, $things);
    }

}

Assuming that is just a test setup and you do need to pass the callback around in a variable, the way to do that is with a callable pseudo type : 假设这只是一个测试设置,而您确实需要在变量中传递回调,则可以使用callable伪类型来实现

class A
{

    protected function echoIt($a, $b) {
        echo $a, $b;
    }

    public function doSomething(array $things) {
        $callback = [$this, 'echoIt'];
        array_map(function ($thing) use ($callback) {
            $callback($thing[0], $thing[1]);
        }, $things);
    }

}

* Since PHP 5.4. *自PHP 5.4起。

class Test
{
    protected function echoIt($a, $b) {
        echo $a, $b;
    }

    public function doSomething(array $things) {
        $theEchoFunction = function($a, $b) {
            return $this->echoIt($a, $b);
        };

        array_map(function($thing) use ($theEchoFunction) {
            $theEchoFunction($thing[0], $thing[1]);
        }, $things);
    }
}

$test = new Test();
$test->doSomething(["1", "2"]);

Result 结果

12

This works for me, I don't know if it works as you expected. 这对我有用,我不知道它是否按您的预期工作。 But to assign the method to a variable, you'd need to make the variable callable. 但是要将方法分配给变量,您需要使变量可调用。 Thus made me think that you can create an anonymous function that is wrapper over the protected method. 因此,我认为您可以创建一个包装在受保护方法之上的匿名函数。 Then you pass that function to the closure. 然后,您将该函数传递给闭包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM