foreach处理对象数组和处理一般数组的区别

foreach处理对象数组:是处理对象的引用,所以经过foreach处理后,对象数组中的对象的数据发生了改变。

foreach处理普通数组:把原数组拷贝一个后,再从中拿出每个元素,我们使用foreach对这些元素进行处理,并不是对原数组的处理,而只是对一个拷贝的处理,所以不管我们怎么改变其值,原数组的值是不会改变的。

例子如下:

/**     
 * 先编写一个简单的类,存储HTML控件数据的类     
 */      
class Element {       
    /**     
     * 这里只作演示,一切简单化处理     
     */      
    protected $name;       
    protected $value;       
      
    public function __construct($name,$value){       
        $this->name = $name;       
        $this->value = $value;       
    }       
           
    public function setName($name){       
        $this->name = $name;       
    }       
}       
      
   $element_list = array();       
   for($i=0;$i<2;$i++){//生成一个拥有2个Element对象的数组       
      $element_list[] = new Element('name_'.$i,'value_'.$i);        
   }       
          
   //先打印出$element_list,查看$element_list当前数据       
   echo '--------old $element_list start--------';       
   print_r($element_list);       
   echo '--------old $element_list end--------';       
          
   /**     
    * 使用foreach对$element_list的元素进行处理     
    * 处理过后,$element_list的元素应该和原来一样,是不变的     
    * 因为foreach不会对原数组的值产生影响     
    */      
   foreach($element_list as $key=>$element){       
      $element->setName('changed');       
   }       
          
   //我们再打印$element_list来看看它当前的值       
   echo '--------new $element_list start--------';       
   print_r($element_list);       
   echo '--------new $element_list end--------';       
/*以下是输出结果        
--------old $element_list start--------     
Array     
(     
    [0] => Element Object     
        (     
            [name:protected] => name_0     
            [value:protected] => value_0     
        )     
    
    [1] => Element Object     
        (     
            [name:protected] => name_1     
            [value:protected] => value_1     
        )     
    
)     
--------old $element_list end---------     
    
-------new $element_list start--------     
Array     
(     
    [0] => Element Object     
        (     
            [name:protected] => changed     
            [value:protected] => value_0     
        )     
    
    [1] => Element Object     
        (     
            [name:protected] => changed     
            [value:protected] => value_1     
        )     
    
)     
--------new $element_list end--------     
*/   

从输出结果可以看出$element_list中对象的数据已经改变,这和原先 我们所了解的使用foreach遍历数组元素,对元素进行处理不会影响到原数组的值是相冲突的,是不是PHP有BUG呢?并不是,出现这种情况的原因 是,PHP5对所有对象都是使用引用,这与PHP4是完全不同的,PHP4在新建对象是要使用&操作符来说明等到的是对象的引用。

  既然是引用,那么$element_list数组里面存储的也都只是 Element对象的引用而不是一个对象拷贝。然后我们回到foreach中来,foreach处理数组时,是把原数组拷贝一个后,再从中拿出每个元素, 我们使用foreach对这些元素进行处理,并不是对原数组的处理,而只是对一个拷贝的处理,所以不管我们怎么改变其值,原数组的值是不会改变的(这个只 对普通的变量有用,PHP5中的对象就不适用了)。如果当前数组是对象数组,那么在PHP5下,其值就是对象的引用,当我们使用foreach对其进行处 理时,情况是这样的,如下:

  1.首先拷贝一个$element_list,我们把它叫做$element_list_copy。在foreach的处理中,所有处理都是对$element_list_copy数组的处理,并不影响原数组$element_list

  2.得到$element_list_copy中的一个元素,对其进行处 理,此时$element_list_copy中的元素也是一个$Element对象的引用,它和$element_list中的值是一样的,都是一 个$Element对象的引用,它们两个指向的是同一块内存空间,所以对$element_list_copy元素的处理和对$element_list 元素的处理,所操作的数据块是相同的,也就是$element_list_copy中的元素改变了,$element_list中的元素也会相应地改变, 因为$element_list_copy和$element_list的元素所指向的是同一块内存,都是同一个$Element对象。

  这也就是为什么经过foreach处理后,对象数组$element_list中的对象的数据发生了改变。千万要注意PHP5下对象数组及一般数组使用foreach处理的区别,不然就很有可能出现让人摸不着头脑的错误产生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值