Как реализовать переменную-член, доступную только для чтения, в PHP?

StackOverflow https://stackoverflow.com/questions/2343790

  •  23-09-2019
  •  | 
  •  

Вопрос

При попытке изменить его создайте исключение.

Это было полезно?

Решение

Я полагаю, что решение для свойств класса будет заключаться в следующем:

  • не определять свойство с именем, которое вас интересует
  • использовать магию __get метод доступа к этому свойству, используя «поддельное» имя
  • определить __set метод, поэтому он выдает исключение при попытке установить это свойство.
  • Видеть Перегрузка, для получения дополнительной информации о магических методах.

Что касается переменных, я не думаю, что возможно иметь переменную, доступную только для чтения, для которой PHP будет генерировать исключение, когда вы пытаетесь записать в нее запись.


Например, рассмотрим этот небольшой класс:

class MyClass {
    protected $_data = array(
        'myVar' => 'test'
    );

    public function __get($name) {
        if (isset($this->_data[$name])) {
            return $this->_data[$name];
        } else {
            // non-existant property
            // => up to you to decide what to do
        }
    }

    public function __set($name, $value) {
        if ($name === 'myVar') {
            throw new Exception("not allowed : $name");
        } else {
            // => up to you to decide what to do
        }
    }
}

Создание экземпляра класса и попытка прочитать свойство:

$a = new MyClass();
echo $a->myVar . '<br />';

Получите ожидаемый результат:

test

При попытке записи в свойство:

$a->myVar = 10;

Получите вам исключение:

Exception: not allowed : myVar in /.../temp.php on line 19

Другие советы

class test {
   const CANT_CHANGE_ME = 1;
}

и вы называете это как test::CANT_CHANGE_ME

Используйте константу.Ключевое слово const

Я знаю, что это старый вопрос, но ответ PASCAL мне очень помог, и я хотел немного добавить к нему.

__get() срабатывает не только для несуществующих свойств, но и для «недоступных», напримерзащищенные.Это позволяет легко создавать свойства, доступные только для чтения!

class MyClass {
    protected $this;
    protected $that;
    protected $theOther;

    public function __get( $name ) {
        if ( isset( $this->$name ) ) {
            return $this->$name;
        } else {
            throw new Exception( "Call to nonexistent '$name' property of MyClass class" );
            return false;
        }
    }

    public function __set( $name ) {
        if ( isset( $this->$name ) ) {
            throw new Exception( "Tried to set nonexistent '$name' property of MyClass class" );
            return false;
        } else {
            throw new Exception( "Tried to set read-only '$name' property of MyClass class" );
            return false;
        }
    }
}

Короткий ответ: вы не можете создать в PHP переменную-член объекта, доступную только для чтения.

Фактически, большинство объектно-ориентированных языков в любом случае считают плохим тоном публичное раскрытие переменных-членов...(C# — большое и уродливое исключение с его конструкциями свойств).

Если вам нужна переменная класса, используйте const ключевое слово:

class MyClass {
    public const myVariable = 'x';
}

Доступ к этой переменной можно получить:

echo MyClass::myVariable;

Эта переменная будет существовать ровно в одной версии независимо от того, сколько разных объектов типа MyClass вы создаете, и в большинстве объектно-ориентированных сценариев это практически бесполезно.

Однако если вам нужна переменная, доступная только для чтения, которая может иметь разные значения для каждого объекта, вам следует использовать закрытую переменную-член и метод доступа (так называемый геттер):

class MyClass {
    private $myVariable;
    public function getMyVariable() {
        return $this->myVariable;
    }
    public function __construct($myVar) {
        $this->myVariable = $myVar;
    }
}

Переменная устанавливается в конструкторе и становится доступной только для чтения из-за отсутствия установщика.Но каждый экземпляр MyClass может иметь собственное значение для myVariable.

$a = new MyClass(1);
$b = new MyClass(2);

echo $a->getMyVariable(); // 1
echo $b->getMyVariable(); // 2

$a->setMyVariable(3); // causes an error - the method doesn't exist
$a->myVariable = 3; // also error - the variable is private
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top