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

时间:2014-09-25 08:44:50

标签: php

在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); });
}

我想在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);
    }
}

我知道只需执行$that = $this;然后将$that传递给闭包就很容易了,但这意味着我无法访问$that->echoIt因为它受到保护。是否可以将方法本身发送给闭包?

我猜这个问题实际上可能是X/Y problem。我想要做的是从闭包内部调用protected方法。我想传递方法,以便闭包不需要知道该类有echoIt方法。

2 个答案:

答案 0 :(得分:1)

具体来说,这样做会很好*(在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);
    }

}

假设这只是一个测试设置而你确实需要在变量中传递回调,那么这样做的方法是使用callable pseudo type

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);
    }

}

*自PHP 5.4起。

答案 1 :(得分:0)

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"]);

结果

12

这对我有用,我不知道它是否按预期工作。但是要将方法分配给变量,您需要使变量可调用。这让我觉得你可以创建一个匿名函数,它是受保护方法的包装器。然后将该函数传递给闭包。