我试图在某个点插入数组:
$hi = "test";
$var2 = "next";
$arr = array(&$hi);
$arr[] = &$var2; // this works
array_splice($arr, 1, 0, &$var2); // this doesn't
为什么尝试使用 splice 将其插入数组失败而使用第一种方法却不行?
快速而肮脏的答案,但请注意,不推荐使用引用调用此函数,并且可能(取决于您的 php 配置)生成警告:
array_splice($arr, 1, 0, array(&$var2));
Hows-and-whys 答案:正在发生的事情非常微妙。当你进行拼接时,因为你已经在那个位置插入了一个引用,所以 $var2 实际上被重新分配了。您可以使用以下代码进行验证:
<?php
$hi = "test";
$var2 = "next";
$arr = array(&$hi);
$arr[] = &$var2; // this works
printf("=== var2 before splice:\n%s\n", var_export($var2, TRUE));
array_splice($arr, 1, 0, &$var2); // this doesn't
printf("=== var2 after splice:\n%s\n", var_export($var2, TRUE));
?>
您将得到以下结果:
=== var2 before splice:
'next'
=== var2 after splice:
array (
0 => 'next',
)
请注意,在拼接之前,$var2 是一个字符串,正如您所期望的那样 ('next')。但是,在拼接之后,$var2 已被替换为包含一个元素的数组,即字符串 'next'。
我认为导致它的原因是文档中所说的:“如果替换不是数组,它将被类型转换为一个(即(数组)$parameter)。” 所以发生的事情是这样的:
我不确定内部发生的事情的所有魔法,但 $var 在拼接期间肯定会被重新分配。请注意,如果您使用第三个变量,因为它没有将某些东西分配给已经作为参考存在的东西,它会按预期工作:
<?php
$hi = "test";
$var2 = "next";
$var3 = "last";
$arr = array(&$hi);
$arr[] = &$var2; // this works
array_splice($arr, 1, 0, &$var3);
printf("=== arr is now\n%s\n", var_export($arr, TRUE));
?>
生成结果:
=== arr is now
array (
0 => 'test',
1 => 'last',
2 => 'next',
)
您可能需要将最后一个参数设为数组,否则根据手册,您将被强制转换为一个。
array_splice( $arr, 1, 0, array( &$var2 ) );
当我尝试像您这样的示例时,我收到一条警告,上面写着“调用时传递引用已被弃用”。根据这个答案:
您可以在 php.ini 文件中将 allow_call_time_pass_reference 设置为 true。但这是一个黑客。
在这里,我正在迭代一个数组($values_arr)并将每个变量的引用存储在另一个数组($params)中。您可以根据需要更改其用法。
$params = array();
$values_arr = array('a', 'b', 123);
foreach ($values_arr as $key=>&$val) {
$params[$key] = &$val;
}
结果
array (size=3)
0 => &string 'a' (length=1)
1 => &string 'b' (length=1)
2 => &int 123