我看到了
另一个问题的这个答案,它启发了我想出了以下解决方案。我没有进行过大量测试,我相信它可以改进(并且需要
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
create_function
的工作方式。你打算如何使用它? - jtbandescreate_function
函数被用作回调函数传递给preg_replace_callback
时,它只会传递一个“matches”参数。但是在函数体内,我需要通过引用访问包含范围内的变量。 - tjm$GLOBALS
数组。 - jtbandes