我一直找不到对这种行为的解释。
对于上下文,我正在使用call_user_func_array
函数为准备好的SQL语句动态绑定参数。我创建了一个简单的函数,它接受一个数组,然后返回一个引用该数组值的数组:
public function returnReferenceArray($array)
{
foreach(array_keys($array) as $value)
{
$refs[] = &$array[$value];
}
return $refs;
}
当直接将其作为call_user_func_array
函数的参数调用时,这一点很好,如下所示:
call_user_func_array(array($stmt, "bind_param"), $obj->returnReferenceArray($bind_params));
然而,当将返回的数组分配给变量时,行为是不同的,如下所示:
$ref_params = $obj->returnReferenceArray($bind_params);
call_user_func_array(array($stmt, "bind_param"), $ref_params);
我收到这个警告:
警告:mysqli_stmt::bind_param()的参数2应为引用,给定值为
我不一定有问题要解决;我只是想弄清楚为什么PHP在赋值和返回时会这样对待引用数组。
更新更多研究
为了更简单地测试这种行为,我通过一系列测试运行了几个数组,以确定在哪些场景中维护数组中包含的引用,而使用函数插入引用似乎根本不起作用。这是我的简化测试:
function returnReferenceArray($array)
{
foreach(array_keys($array) as $value)
{
$refs[] = &$array[$value];
}
return $refs;
}
function referenceReferenceArray($varray, &$rarray)
{
foreach(array_keys($varray) as $value)
{
$rarray[] = &$varray[$value];
}
}
$value_array = array(
"foo" => 1,
);
$ref_array[] = &$value_array["foo"]; //reference is maintained
$ref_array = array();
$ref_array = returnReferenceArray($value_array); //reference is NOT maintained
$ref_array = array();
referenceReferenceArray($value_array, $ref_array); //reference is NOT maintained
以下是演示行为的输出要点:
https://gist.github.com/twistofreality/3b4760aba008f7620d10
话虽如此,由于将我的函数作为call_user_func_array
的参数调用对bind_param
有效,因此必须维护某种引用,但是,鉴于我的测试结果,我现在真的对定义引用数组行为的机制感到困惑。
我希望有人能指出一些我忽略的显而易见的事情。
另一更新
看起来这是一个覆盖范围很广的地区。在发布之前,我确实在SO上搜索了一段时间,但后来我在"相关"部分注意到了这一点:
我的PHP引用数组是";神奇地";成为一组价值观。。。为什么?
无论如何,当我直接将函数作为call_user_func_array
的参数调用,而不是将函数的结果分配给另一个变量时,我仍然不确定为什么这会起作用。如果有人对此有任何见解,那就太好了。
这是因为PHP赋值会创建一个副本。IOW,它是按价值分配的。请参阅有关分配的手册。
尝试
$ref_params = &$obj->returnReferenceArray($bind_params);
以获得对引用数组的引用(我还没有尝试过…所以请告诉我们它是否有效)。