Как избежать динамических свойств в PHP (поднять ошибку при установке необъявленного свойства)

Пример:

error_reporting(E_ALL | E_STRICT);
class Test {}
$obj = new Test();
$obj->undeclared = "oops";    // I want an error here !! :(
echo $obj->algo;              // oops 

Я тестировал его на PHP 5.2.11 и 5.3.0.

Мне не нужны динамические свойства в моих объектах.
Можно ли заставить PHP выражать ОШИБКУ в этой ситуации?

Ответы

Ответ 1

Используйте __ set()?

<?php
class Test {

    public $bar;

    public function __set($name, $value) {
        throw new Exception('Cant set!');
    }
}

$obj = new Test;
$obj->bar = 'foo';
$obj->foo = 'evil';
?>

Ответ 2

В разделе "Я не хочу динамических свойств в моих объектах". Я предполагаю, что вы имеете в виду, что вы не хотите, чтобы ваши объектные переменные никогда не были undefined? Если это так, просто создайте все переменные класса. Вы даже можете сделать их статичными, если вы действительно обеспокоены тем, что они являются постоянными, а не динамическими.

Если вы попытаетесь получить доступ к переменной объекта, которая не существует, PHP будет вызывать ошибку. Ответ, который предложил radmen, фактически заставил бы его сделать так, чтобы вместо того, чтобы бросать ошибку, PHP динамически создавал переменные объекта undefined для вас на лету.

Ответ 3

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

  1. защитить использование этого класса от перезаписи ваших свойств
  2. защитить орфографические ошибки переменных (особенно ошибки верблюдов) например, $this-> callerID возвращается, как и ожидалось, но $this-> callerId выдает исключение и предотвращает ошибки кода.
    public function __set($name,$value) {
        switch ($name) {
            default:
                // we don't allow any magic properties set or overwriting our properties
                try {
                    $error = "Assignment of {$name} in " . static::class . ' not allowed because it is a magic variable or read-only property.';
                    throw new \RuntimeException($error);
                } catch ( \RuntimeException $e ) {
                    echo 'Caught exception: ' . $e->getMessage() . PHP_EOL;
                }

        }
    }

    public function __get($name)
    {
        switch ($name) {
            default:
                // we don't allow any magic properties
                try {
                    $error = "var {$name} is not a property of " . static::class . '.';
                    throw new \RuntimeException($error);
                } catch ( \RuntimeException $e ) {
                    echo 'Caught exception: ' . $e->getMessage() . PHP_EOL;
                }
        }
        return null;
    }

    public function __isset($name)
    {
        switch ($name) {
            default:
                return false;
        }
    }