Почему вы можете изменить значение закрытых атрибутов (которые являются объектами)? - PullRequest
0 голосов
/ 22 января 2012

Может кто-нибудь сказать мне, почему это возможно?Закрытый атрибут должен изменяться только из самого класса.s :: $ c читабельно (getC ()), но почему я могу писать в него?

<?php

class s{

    private $c;

    public function __construct() {
        $this->c = new t;
    }

    public function getC() {
        return $this->c;
    }

}

class t {

    public $a = 1;
    public $b = 2;

}

$x = new s();

$x->getC()->a = 5;

echo $x->getC()->a;
?>

Вывод: 5

Ответы [ 3 ]

5 голосов
/ 22 января 2012

Вы выставили $c, сделав метод getC() общедоступным. Теперь любой / любой может получить доступ к $c с помощью функции getC(), и любой мог бы всегда получить доступ к $a, поскольку он был общедоступным.


Если вы хотите, чтобы значения $a и $b класса t были доступны только для чтения, вы можете сделать их закрытыми, каждое с методом доступа, таким как getA() и getB(). Например:

class s {
    private $c;

    public function __construct() {
        $this->c = new t;
    }

    public function getC() {
        return $this->c;
    }
}

class t {
    private $a = 1;
    private $b = 2;

    public function getA() {
        return $this->a;
    }

    public function getB() {
        return $this->b;
    }
}
3 голосов
/ 22 января 2012

когда php возвращает объект, он не дублирует его, он возвращает указатель (ссылку) на объект в памяти. поэтому каждое внесенное вами изменение будет влиять на исходный объект.

чтобы предотвратить это, вы можете клонировать объект перед его возвратом

public function getC() {
    return clone $this->c;
}
1 голос
/ 22 января 2012

Это ожидаемое поведение.

«Приватный» означает, что вы не можете использовать $x->c напрямую.$x->getC() является функцией s, и поэтому имеет доступ к закрытым членам s.getC является общедоступным, поэтому вы можете вызывать этот метод где угодно.

Короче говоря, поскольку вы выставили getC ("получатель" для C), вы можете прочитать значение C в любом месте.То, что вы не можете сделать, это $x->getC() = 2;.

...