Объектный метод PHP не ведет себя так, как я ожидаю - PullRequest
0 голосов
/ 06 марта 2012

Я не совсем понимаю, почему вывод этого кода равен '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 ]

6 голосов
/ 06 марта 2012

Вы должны вернуть массив по ссылке . Таким образом, 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.

Из возвращаемых ссылок подстраница:

В отличие от передачи параметров, здесь вы должны использовать & в обоих местах - для указать, что вы хотите вернуть по ссылке, а не копию, и указать, что привязка ссылки, а не обычное назначение, должна быть сделано

Обратите внимание, что хотя это и делает работу, вопрос в том, является ли это хорошей практикой. Изменяя членов класса за пределами самого класса, может стать очень трудно отследить приложение.

2 голосов
/ 06 марта 2012

Когда вы unset($tobj_arr[0]); передаете возвращаемое значение вызова функции, а не фактическое свойство объекта.

Когда вы снова вызываете функцию, вы получаете свежую копию свойства объекта, которая еще не была изменена, так как вы добавили к ней 5.

Так как само свойство является публичным, попробуйте изменить: unset($tobj_arr[0]);

Кому: unset($t->arr[0]);

И посмотрите, даст ли это вам результат, который вы ищете.

2 голосов
/ 06 марта 2012

Поскольку по умолчанию для массива передается «copy on write», getArr () должен возвращаться по ссылке:

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

[snip]

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

Для массивов, которые являются объектами, используйте ArrayObject . Расширение ArrayObject, вероятно, лучше в вашем случае.

0 голосов
/ 06 марта 2012

Вы получаете «1», потому что вы спрашиваете PHP, сколько элементов в массиве, используя count.Удалить счетчик и использовать print_r ($ tobj_arr_fresh)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...