PHP引用导致数据损坏

参见英文答案 > Strange behavior Of foreach2个
我正在编写PHP代码来对数组中的每个值进行一些转换,然后从外部源(MysqL游标或者说另一个数组)向数组添加一些值.如果我使用foreach和引用来转换数组值
<?PHP
$data = array('a','b','c');

foreach( $data as &$x ) 
    $x = strtoupper($x);

$exTradata = array('d','e','f'); 
// actually it was MysqL cursor

while( list($i,$x) = each($exTradata) ) {
    $data[] = strtoupper($x);
}

print_r($data);
?>

(Here it is in PHPfiddle)

数据被破坏了.所以我明白了

Array ( [0]=>A [1]=>B [2]=> [3]=>D [4]=>E [5] =>F )

代替

Array ( [0]=>A [1]=>B [2]=>C [3]=>D [4]=>E [5] =>F )

当我不使用引用和写

foreach( $data as &$x ) 
    $x = strtoupper($x);

当然,转换不会发生,但数据也不会被破坏,所以我得到了

Array ( [0]=>a [1]=>b [2]=>c [3]=>D [4]=>E [5] =>F )

如果我写这样的代码

<?PHP
$result = array();

$data1 = array('a','c');

foreach( $data1 as $x ) 
    $result[] = strtoupper($x);

$data2 = array('d',$x) = each($data2) ) {
    $result[] = strtoupper($x);
}

print_r($result);
?>

一切都按预期工作.

Array ( [0]=>A [1]=>B [2]=>C [3]=>D [4]=>E [5] =>F )

当然,我复制数据解决了这个问题.但我想了解这个参考的奇怪问题是什么,以及如何避免这样的麻烦.也许在代码中使用PHP引用通常是不好的(就像很多人说的关于C指针)?

PHP语言的引用机制具有特定的功能,这在其他编程语言中并不常见.通常接受的是,对象反映了通过对其属性的任何引用而对其属性进行的所有更改.但是对引用本身的赋值要么被禁止,要么将引用指向另一个对象.而不是这样,PHP中的引用赋值将整个底层对象(引用指向的对象)替换为指定的一个.所以
$a = 1; $b = 2;
$r = &$a;
$r = $b;
echo $a; // will output '2'

这对于分配是正确的,但对于未设置的调用不是真的,它不会破坏底层对象,而是打破引用和指向对象之间的链接.

$a = 1; $b = 2;
$r = &$a;
unset($r); //!
$r = $b;
echo $a; // will output '1'

这种参考行为在某些情况下很有用,但它常常被误解,导致出现问题的问题.

要避免PHP引用的问题,您应该:

>尽早取消每个参考(在不需要的时候).

所以,这段代码将起作用

<?PHP
$data = array('a','c');

foreach( $data as &$x ) 
    $x = strtoupper($x);
unset($x);

$exTradata = array('d',$x) = each($exTradata) ) {
    $data[] = strtoupper($x);
}

print_r($data);
?>

>通常,在多个控制结构中重用局部变量名称被认为是一种不好的方式.

所以下面的代码也可以使用

<?PHP
$data = array('a',$y) = each($exTradata) ) {
    $data[] = strtoupper($y);
}

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...