gpt4 book ai didi

php - __callStatic()、call_user_func_array()、引用资料和 PHP 5.3.1

转载 作者:可可西里 更新时间:2023-11-01 12:37:17 24 4
gpt4 key购买 nike

我一直在阅读关于 SO 和其他地方的文章,但是我似乎找不到任何结论。

有没有什么方法可以有效地通过这个调用堆栈传递引用,从而产生下面示例中描述的所需功能?虽然这个例子并没有试图解决它,但它确实说明了问题:

class TestClass{
// surely __call would result similarly
public static function __callStatic($function, $arguments){
return call_user_func_array($function, $arguments);
}
}

// note argument by reference
function testFunction(&$arg){
$arg .= 'bar';
}

$test = 'foo';
TestClass::testFunction($test);

// expecting: 'foobar'
// getting: 'foo' and a warning about the reference
echo $test;

为了激发潜在的解决方案,我将在此处添加摘要详细信息:

仅关注 call_user_func_array(),我们可以确定(至少对于 PHP 5.3.1)您不能通过引用隐式传递参数:

function testFunction(&$arg){
$arg .= 'bar';
}

$test = 'foo';
call_user_func_array('testFunction', array($test));
var_dump($test);
// string(3) "foo" and a warning about the non-reference parameter

通过显式传递数组元素 $test 作为引用,我们可以缓解这种情况:

call_user_func_array('testFunction', array(&$test));
var_dump($test);
// string(6) "foobar"

当我们使用 __callStatic() 引入类时,通过引用显式调用时间参数似乎如我预期的那样执行,但发出弃用警告(在我的 IDE 中):

class TestClass{
public static function __callStatic($function, $arguments){
return call_user_func_array($function, $arguments);
}
}

function testFunction(&$arg){
$arg .= 'bar';
}

$test = 'foo';
TestClass::testFunction(&$test);
var_dump($test);
// string(6) "foobar"

TestClass::testFunction() 中省略引用运算符导致 $test 按值传递给 __callStatic(),并且当然是通过 call_user_func_array() 按值作为数组元素传递给 testFunction()。这会导致警告,因为 testFunction() 需要引用。

四处寻找,一些额外的细节浮出水面。 __callStatic() 定义,如果编写为通过引用返回(public static function &__callStatic())没有可见的效果。此外,将 __callStatic() 中的 $arguments 数组的元素重铸为引用,我们可以看到 call_user_func_array() 有点像预期的那样工作:

class TestClass{
public static function __callStatic($function, $arguments){
foreach($arguments as &$arg){}
call_user_func_array($function, $arguments);
var_dump($arguments);
// array(1) {
// [0]=>
// &string(6) "foobar"
// }
}
}

function testFunction(&$arg){
$arg .= 'bar';
}

$test = 'foo';
TestClass::testFunction($test);
var_dump($test);
// string(3) "foo"

这些结果是预期的,因为 $test 不再通过引用传递,更改不会传回它的范围。然而,这证实了 call_user_func_array() 实际上按预期工作,并且问题肯定仅限于调用魔法。

进一步阅读后,它似乎是 PHP 处理用户函数的“错误”,__call()/__callStatic() 魔法.我仔细阅读了现有或相关问题的错误数据库,并找到了一个,但无法再次找到它。我正在考虑发布另一份报告,或请求重新打开现有报告。

最佳答案

这很有趣。

TestClass::testFunction(&$string);

这有效,但它也会抛出一个调用时间引用传递警告。

主要问题是 __callStatic 的第二个参数按值传入。它正在创建数据的副本,除非该数据已经是一个引用。

我们可以这样复制调用错误:

call_user_func_array('testFunction', array( $string ));
// PHP Warning: Parameter 1 to testFunction() expected to be a reference, value given

call_user_func_array('testFunction', array( &$string ));
echo $string;
// 'helloworld'

我尝试修改 __callStatic 方法以通过引用深度复制数组,但这也不起作用。

我很确定由 __callStatic 引起的立即复制将成为这里的 killer ,如果没有足够的跳圈,你将无法做到这一点贴纸,语法方面。

关于php - __callStatic()、call_user_func_array()、引用资料和 PHP 5.3.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5602616/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com