php - 将 create_function 用作闭包时从包含作用域引用变量。 PHP

标签 php reference closures

使用真正的闭包,我们可以做到,

function foo(&$ref)
{
    $inFn = function() use (&$ref)
    {   
        $ref = 42; 
    };  

    $inFn();
}

因此无需在对 $inFn 的调用中将其传递即可修改引用。

如果我们替换,

    $inFn = function(... 

    $inFn = create_function(...

是否有任何(简单而干净的)方法来做同样的事情;通过引用引用包含范围的变量没有显式传递它$inFn

最佳答案

我遇到了 this answer to another question这启发了我想出以下内容。我没有对它进行过大量测试,我相信它可以改进(需要 exec 调用是一种耻辱),但它似乎解决了我的问题。

class create_closure
{
    private 
        $_cb  = null,
        $_use = array();

    public function __construct(array $use, $closure_args, $closure_body)
    {   
        $use_args = implode(array_keys($use), ',');

        $this->_cb = create_function(
            $use_args.($use_args==='' OR $closure_args==='' ? '' : ',').$closure_args,
            $closure_body
        );  

        $this->_use = array_values($use);

    }   

    public static function callback(array $use, $closure_args, $closure_body)
    {   
        $inst = new self($use, $closure_args, $closure_body);
        return array($inst, 'exec');
    }   

    public function exec()
    {   
        return call_user_func_array(
                $this->_cb,
                array_merge($this->_use, func_get_args())
        );  
    }   
}

你可以这样使用它:

function foo(&$ref)
{
    $inFn = new create_closure(
        array('$ref'=>&$ref), 
        '', 
        '$ref=42;'
    );
    $inFn->exec();
}

$x = 23;
echo 'Before, $x = ', $x, '<br>';
foo($x);
echo 'After,  $x = ', $x, '<br>';

哪个返回:

Before, $x = 23
After, $x = 42

或者像这样:

function bar()
{           
    $x = 0;
    echo 'x is ', $x, '<br>';

    $z = preg_replace_callback(
        '#,#',
        create_closure::callback(
            array('$x'=>&$x),
            '$matches',
            'return ++$x;
            '
        ),
        'a,b,c,d'
    );

    echo 'z is ', $z, '<br>';
    echo 'x is ', $x, '<br>';
}       

bar(); 

哪个返回:

x is 0
z is a1b2c3d
x is 3

关于php - 将 create_function 用作闭包时从包含作用域引用变量。 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6486570/

相关文章:

PHP 常量引用

php - CodeIgniter 不断为 int 值插入 2147483647

c++ - 将数组传递给函数 C++

swift - 在嵌套闭包中捕获值

javascript - 在 vscode 中调试 JavaScript 时如何找到当前函数的闭包

php - 在第三方调用的 WebHook 中验证用户

php - POST 方法和数组

c# - 如何获取可变字符串列表?

c++ - 关于多态性,引用和指针是否相等?

javascript - eventListener 内的代码没有立即调用?