【问题标题】:How to make differently indexed PHP arrays point to the same objects如何使不同索引的 PHP 数组指向相同的对象
【发布时间】:2011-01-04 10:28:59
【问题描述】:

在一个类中,我有三个数组(作为实例变量),它们都必须指向相同的对象。第一个是我从某个外部函数返回的数字索引数组。第二个数组必须按名称索引相同的对象。第三个是其他财产。这是为了通过这些属性快速访问。所以重点是:我使用哪个数组来访问和修改对象并不重要。

但它无法实现。我知道 PHP 参考资料。我知道java参考。我知道 C 指针,但我无法实现 - 无论我尝试放置与号 (=&) 的任何位置。

class xxx {

  private $objs;
  private $objsByName;

  public function __construct() {

    $this->objs = getObjs();
    $this->objsByName = array();
    foreach($this->objs as $obj) {
      $this->objsByName[$obj->getName()] = $obj;
    }
  }

}

这里没有我没试过用=&代替=的地方

我错过了什么?

【问题讨论】:

  • 欢迎来到 StackOverflow。您可以使用{} 工具栏按钮格式化源代码(这次我已经为您完成了)。不要忘记将解决您问题的最佳答案标记为已接受

标签: php arrays object reference


【解决方案1】:

用这个替换你的 foreach 循环。

for($i = 0 , $n = count($this->objs); $i < $n ; $i ++){

$this->objsByName[$this->objs[$i]->getName()] = &$this->objs[$i];

}

这会解决你的问题:)

谢谢!

侯赛因。

【讨论】:

    【解决方案2】:

    在 PHP 中,对象总是通过引用传递 (you cannot copy an object unless you use clone keyword)。这段代码说明了这一点:

    <?php
    
    class AnObject{
        private $name;
        public $count=0;
    
        public function __construct($name){
            $this->name = $name;
        }
    
        public function getName(){
            return $this->name;
        }
    }
    
    function getObjs(){
        return array(
            new AnObject('One'),
            new AnObject('Two'),
            new AnObject('Three'),
        );
    }
    
    
    class xxx {
    
      private $objs;
      private $objsByName;
    
      public function __construct() {
    
        $this->objs = getObjs();
        $this->objsByName = array();
        foreach($this->objs as $obj) {
          $this->objsByName[$obj->getName()] = $obj;
        }
      }
    
      public function alterAnObjectByName($name){
          $this->objsByName[$name]->count++;
      }
    
    }
    
    $x = new xxx;
    var_dump($x);
    $x->alterAnObjectByName('Two');
    var_dump($x);
    

    问题可能出在其他地方。

    【讨论】:

      【解决方案3】:

      在 php 手册中标记这部分: http://php.net/manual/en/control-structures.foreach.php

      除非引用了数组,否则 foreach 对指定数组的副本而不是数组本身进行操作。 foreach 对数组指针有一些副作用。不要在 foreach 期间或之后依赖数组指针而不重置它。

      所以你的 $obj 是一个副本。

      我没有测试 Hussain 的代码,但这看起来是个不错的选择 :)

      【讨论】:

        【解决方案4】:

        PHP 总是使用 copy on write 函数,很有可能您的对象在更改之前都是相同的。

        为避免错误,您应该说其中一个数组包含数据,而其他数组只是索引。

        使用索引查找id,并使用以id为索引的数据数组读取和修改数据。

        【讨论】:

          【解决方案5】:

          在 PHP5 中,您可以将 &amp; 添加到 as 变量中,以使 foreach 循环不克隆对象:

          foreach($this->objs as &$obj) {
             $this->objsByName[$obj->getName()] = &$obj;
          }
          

          参考:http://php.net/manual/en/control-structures.foreach.php

          p/s:我不确定是否需要 foreach 体内的 &amp;,但只需添加它以确保安全。或者您可以尝试删除它,看看是否需要它。

          【讨论】:

            猜你喜欢
            • 2016-09-26
            • 1970-01-01
            • 2022-01-08
            • 2012-01-01
            • 2016-03-08
            • 2012-08-13
            • 2021-01-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多