По умолчанию поведение геттера по умолчанию, если свойство не выходит

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

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

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

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, но я хотел бы, чтобы это оставалось как можно более интуитивно понятным, несмотря на аргумент, что выполнение таких операций противоречит здравому смыслу. Две частные собственности очень тесно связаны друг с другом. Когда один из них установлен, он логически повлияет на другие.

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


person Nathaniel    schedule 12.03.2011    source источник
comment
В чем именно заключается ваш вопрос?   -  person Jon    schedule 12.03.2011
comment
остайтесь как можно более интуитивным магия никогда не бывает интуитивной.   -  person Boris Guéry    schedule 12.03.2011
comment
Кстати, что вы подразумеваете под поведением по умолчанию поведение PHP по умолчанию или ваш родительский класс?   -  person Boris Guéry    schedule 12.03.2011
comment
@Boris: Возможно, лучшая формулировка не интуитивно понятна. Возможно, мне следовало сказать «логично». Когда пара переменных тесно связана, как в моем случае использования, когда одна обновляется, она логически делает недействительной другую, если она также не обновляется. И под поведением по умолчанию я подразумеваю выдачу собственных ошибок, если свойство недоступно, возврат значения свойства, если оно общедоступное, и т. д., поэтому поведение PHP по умолчанию.   -  person Nathaniel    schedule 13.03.2011


Ответы (2)


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);
 }

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

person mario    schedule 13.03.2011
comment
Я понимаю, что вы здесь говорите, хотя я не понимаю вот что: Но вы можете использовать get_object_vars, чтобы отфильтровать частные переменные, по крайней мере, из базового класса. get_object_vars получает в соответствии с областью действия, поэтому он будет возвращать все нестатические свойства во всем классе, снова открывая нежелательные частные переменные. Если вы не имеете в виду, что get_object_vars будет фильтровать приватные данные родителя, и в этом случае это может помочь больше, чем я думаю, в его нынешнем виде. Я еще не играл с get_object_vars во всех различных областях. - person Nathaniel; 14.03.2011
comment
Да особо не поможет. Вам придется использовать ReflectionClass для получения точных результатов. - person mario; 14.03.2011

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

person Ben    schedule 12.03.2011
comment
Здесь он пишет один большой геттер/сеттер, проиндексированный по имени свойства. Лучше всего придерживаться того, чего научились ожидать другие программисты. - person Ben; 13.03.2011