当使用create_function作为闭包时,从包含范围引用变量. PHP

前端之家收集整理的这篇文章主要介绍了当使用create_function作为闭包时,从包含范围引用变量. PHP前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用真正的关闭,我们可以做,
function foo(&$ref)
{
    $inFn = function() use (&$ref)
    {   
        $ref = 42; 
    };  

    $inFn();
}

因此修改引用而不必在调用$inFn时传递它.

如果我们更换,

$inFn = function(...

$inFn = create_function(...

有没有(简单和干净)的方式做同样的事情?通过引用引用包含范围的变量,而不将它明确地传递给$inFn?

我遇到了 this answer to another question,这激发了我以下想法.我没有大量测试它,我确信它可以改进(并且执行程序调用的需要是一个耻辱),但它似乎解决了我的问题.
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_body)
    {   
        $inst = new self($use,$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,'<br>';

哪个返回:

06002

或者像这样:

function bar()
{           
    $x = 0;
    echo 'x is ','<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 ','<br>';
}       

bar();

哪个返回:

06004

猜你在找的PHP相关文章