PHP对象方法不像我期望的那样

时间:2012-03-06 17:29:47

标签: php arrays reference

我不太明白为什么这段代码的输出为'1'。 我的猜测是php的行为与我以前使用的大多数其他OO语言不同,因为php使用的数组不能是对象。更改类返回的数组不会更改类中的数组。我如何让类返回一个我可以编辑的数组(并且与该类中的数组具有相同的地址)?

<?php
    class Test
    {
        public $arr;
        public function __construct()
        {
            $this->arr = array();
        }

        public function addToArr($i)
        {
            $this->arr[] = $i;
        }

        public function getArr()
        {
            return $this->arr;
        }
    }

    $t = new Test();
    $data = 5;
    $t->addToArr($data);

    $tobj_arr = $t->getArr();
    unset($tobj_arr[0]);

    $tobj_arr_fresh = $t->getArr();
    echo count($tobj_arr_fresh);
?>

编辑:我预计输出为0

4 个答案:

答案 0 :(得分:6)

您必须返回数组by reference。这样,php返回对数组的引用,而不是副本。

<?php
    class Test
    {
        public $arr;
        public function __construct()
        {
            $this->arr = array();
        }

        public function addToArr($i)
        {
            $this->arr[] = $i;
        }

        public function & getArr() //Returning by reference here
        {
            return $this->arr;
        }
    }

    $t = new Test();
    $data = 5;
    $t->addToArr($data);

    $tobj_arr = &$t->getArr(); //Reference binding here
    unset($tobj_arr[0]);

    $tobj_arr_fresh = $t->getArr();
    echo count($tobj_arr_fresh);
?>

返回0。

来自returning references子页面:

  

与参数传递不同,这里你必须使用&amp;在这两个地方 - 到   表示您希望通过引用而不是副本返回   表明引用绑定,而不是通常的赋值,应该   完成

请注意,虽然这可以完成工作,但问题是这是一个好习惯。通过更改类本身之外的类成员,跟踪应用程序变得非常困难。

答案 1 :(得分:2)

因为默认情况下数组是通过“copy on write”传递的,所以getArr()应该通过引用返回:

    public function &getArr()
    {
        return $this->arr;
    }

[snip]

$tobj_arr = &$t->getArr();

对于作为对象的数组,请使用ArrayObject。在您的情况下,扩展ArrayObject可能更好。

答案 2 :(得分:2)

当你unset($tobj_arr[0]);传递函数调用的返回值时,而不是对象的实际属性。

当您再次调用该函数时,您将获得该对象属性的新副本,该属性尚未被修改,因为您已向其添加了5。

由于酒店本身是公开的,请尝试更改: unset($tobj_arr[0]);

收件人:unset($t->arr[0]);

看看是否能为您提供所需的结果。

答案 3 :(得分:-2)

你得到“1”,因为你通过使用count询问PHP在数组中有多少元素。删除计数并使用print_r($ tobj_arr_fresh)