PHP 引用导致数据损坏

标签 php reference

<分区>

我正在编写 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','b','c');

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

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

while( list($i,$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语言的引用机制有其独特之处,这是其他编程语言所不具备的。人们普遍认为,对象反射(reflect)了通过对它的任何引用对其属性所做的所有更改。但是对引用本身的赋值要么被禁止,要么使引用指向另一个对象。取而代之的是,在 PHP 中对引用的赋值将整个底层对象(通过引用指向的对象)替换为被赋值的对象。所以

$a = 1; $b = 2;
$r = &$a;
$r = $b;
echo $a; // will output '2'

这适用于赋值,但不适用于 unset 调用,它不会破坏底层对象,但会断开引用和指向对象之间的链接。

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

这种引用行为在某些情况下很有用,但它经常被误解,导致问题如问题所示。

为了避免 PHP 引用出现问题,您应该:

  • 尽早取消设置每个引用(在不需要时)。

所以,这段代码可以工作

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

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

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

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

print_r($data);
?>
  • 通常认为在多个控制结构中重用局部变量名是一种不好的风格。

所以下面的代码也可以工作

<?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,$y) = each($extradata) ) {
    $data[] = strtoupper($y);
}

关于PHP 引用导致数据损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19593835/

相关文章:

php - dompdf 不显示由 PHP 文件生成的图像

php - 从mysql数据库中选择查询

php - 有条件的按计数排序

ios - 如何在 touchesBegan : and touchesEnded:? 之间以一致的方式跟踪触摸

c++ - 使用存储在 vector 中的对象的正确方法是什么?

javascript - 在其他 php 文件中使用 Javascript 显示表单结果

PHP 显示缩小和调整大小的图像

C++ 右值引用构造函数对简单类型(Vector3、Matrix 等)的好处

c++ - 为什么不允许指针的运算符重载工作?

c# - 初始化变量时使用新内存位置的标准是什么?