По умолчанию используется поведение получателя по умолчанию, если свойство не завершается - PullRequest
1 голос
/ 12 марта 2011

В настоящее время мне нужно расширить класс, чтобы добавить к нему функциональность (у меня нет доступа к базовому классу для его изменения), и я сталкиваюсь с этим вопросом.

По сути, мне нужна волшебная функция получения, которая возвращает набор приватных переменных, если они запрашиваются, но в остальном по умолчанию используется поведение по умолчанию. Мне нужно, чтобы эти свойства были частными, чтобы использовать функцию автоматического набора для автоматической синхронизации некоторых данных.

Тем не менее, вот пример кода:

class newClass extends baseClass {
    private $private1;
    private $private2;

    ...

    public function __get($name) {
        if($name == 'private1') return $this->private1;
        if($name == 'private2') return $this->private2;
        ... (and so on)
        // and here, it should default back to it's default behavior (throwing
        // an error on getting invalid/inaccessable property, etc.)
        // I cannot just use property_exists, because there may or may not be
        // private variables in the base class that should not be exposed.
    }
    public function __set($name,$val) {
        // I use this to do some automatic syncing when the two private variables
        // above are set. This needs to be triggered, hence the private variables
        // in the first place.
    }
}

Я знаю, я мог бы использовать функции getProperty / setProperty, но я бы хотел, чтобы это оставалось как можно более интуитивно понятным, несмотря на аргумент, что выполнение таких операций нелогично. Два частных свойства очень тесно связаны друг с другом. Когда один из них установлен, он логически будет влиять на другие.

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

Ответы [ 2 ]

1 голос
/ 13 марта 2011

PHP не имеет встроенного свойства, как другие языки, __get и __set действительно то, что вы должны использовать здесь. Но это немного больше работы, чтобы выполнить.

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

 function __get($name) {
     static $r; if (!isset($r)) { $r = new ReflectionClass($this); }

     if (($p = $r->getProperty($name)) and $p->isPublic()) {
         return $this->$name;
     }
     elseif (method_exists($this, "get_$name")) {
         return $this->{"get_$name"}();
     }
     else trigger_error("inaccessible property ->$name", E_USER_NOTICE);
 }

Для возврата к поведению по умолчанию лучшее, что вы можете сделать, это вручную вывести сообщение об ошибке.

0 голосов
/ 12 марта 2011

Не делайте этого, используйте getter / setters.Они точно такой же объем работы, что и вы здесь.

...