如何使不同索引的 PHP 数组指向相同的对象

发布于 2024-10-10 09:34:34 字数 561 浏览 1 评论 0原文

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

但它无法实现这一点。我了解 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;
    }
  }

}

这里没有任何地方我没有尝试过用 =& 替换 = 。

我缺少什么吗?

Within a class I have three arrays (as instance variables) that must all point to the same objects. The first is a numerically indexed array that I get back from some external function. The second array must index the same objects by their name. The third by some other property. This is for fast access via those properties. So the point is: it shouldn't matter which array I use to access an object and modify it.

Yet it can't make it happen. I know about PHP references. I know about java references. I know about C pointers, but I can't make it happen - wherever I try to place the ampersand (=&).

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;
    }
  }

}

There is no place here where I have not tried replacing = with =&

I am missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

如果没结果 2024-10-17 09:34:34

用这个循环替换你的 foreach 循环。

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

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

}

这将解决您的问题:)

谢谢!

侯赛因。

Replace your foreach loop with this one.

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

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

}

This will solve your problem :)

Thanks!

Hussain.

朮生 2024-10-17 09:34:34

在 PHP 中,对象始终通过引用传递(除非使用 <代码>克隆关键字)。此代码说明了这一点:

<?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);

问题可能出在其他地方。

In PHP, objects are always passed by reference (you cannot copy an object unless you use clone keyword). This code illustrates this:

<?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);

The issue is probably somewhere else.

不顾 2024-10-17 09:34:34

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

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

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

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

Mark this part from the php manual:
http://php.net/manual/en/control-structures.foreach.php

Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.

So your $obj is a copy.

I have not tested Hussain's code, but that looks like a good option :)

舟遥客 2024-10-17 09:34:34

PHP 总是使用写时复制函数,很可能您的对象在发生更改之前都是相同的。

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

使用索引查找 id,并使用按 id 索引的数据数组来读取和更改数据。

PHP always use copy on write functions, chances are that your objects will be same until one is changed.

To avoid errors you should say that one of your array contains the data and that thee others are just indexes.

Use the index to find the id, and use tha data array, indexed by id, to read and alter data.

梦里°也失望 2024-10-17 09:34:34

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

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

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

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

In PHP5 you can add & to the as variable to make the foreach loop not clone the object:

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

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

p/s: I'm not sure if the & inside the foreach body is needed or not but just add it to be safe. Or you can try removing it to see if it's needed or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文