Intereting Posts
Как я могу получить все перестановки в PHP без последовательных дубликатов? Symfony2: Поиск маршрута «GET / lucky / number» не найден. Как передать дополнительную переменную в symfony form builForm Function Пользовательская конечная точка WooCommerce API v3 Каков правильный способ настройки и использования php-resque? Неустранимая ошибка: время выполнения 30 секунд превышено в phpmyadmin Разбор доменного имени из URL-адреса в PHP Переходы строк заголовка PHP и HTTP: какой символ используется для представления? Каков правильный способ обработки данных $ _POST в MVC? MySQL: как бы я стал показывать простые «категории» для этого? WordPress – Использование функций вне wordpress Почему короткие короткие теги «echo» постоянно включены с PHP 5.4? Возможно ли представить две формы одновременно? Как мне создать кнопку выхода из системы в моей строке меню, которая отображается помощником вида? Как выполнить javascript на сервере node.js

PHP Унаследованный родительский метод не может получить доступ к частной собственности ребенка

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

В словах: у меня есть базовый класс, который предоставляет некоторые методы для всех дочерних элементов, но не содержит никакого свойства. Мой ребенок наследует эти методы, которые должны использоваться для доступа к свойствам дочернего элемента. Если свойство дочернего объекта protected или public , все работает нормально, но если свойство дочернего объекта является private , оно не выполняется без ошибок (просто ничего не происходит).

В коде:

 class MyBaseClass { public function __set($name, $value) { if(!property_exists($this, $name)) throw new Exception("Property '$name' does not exist!"); $this->$name = $value; } } class ChildClass extends MyBaseClass { public $publicProperty; protected $protectedProperty; private $privateProperty; } $myChild = new ChildClass(); $myChild->publicProperty = 'hello world'; //works of course! $myChild->protectedProperty = 'hello world'; //works as expected $myChild->privateProperty = 'hello world'; //doesn't work? 

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

Это специально? Я что-то делаю неправильно? или мой подход просто дерьмо по дизайну?

Предыстория: Моя оригинальная идея: вся динамическая вещь о __set() – это то, что мне не нравится. Обычно частная собственность никогда не должна быть доступна извне, поэтому я реализовал металирование __set- и __get-методов в моем конечном базовом классе (из которого наследуются все классы).

Теперь я хочу динамически порождать экземпляр из файла XML и, следовательно, нуждаться в доступе к свойствам. Я сделал правило, что любой XML-экземплярный класс должен реализовать магический __set() и поэтому может быть создан динамически. Вместо того, чтобы внедрять его в каждый класс, который может быть порожден однажды, я решил наследовать их из класса под названием class Spawnable { } который предоставляет необходимый метод __set.

В этом разница между private и protected . Частные методы и свойства не могут быть унаследованы или достигнуты. Вам нужно будет заменить их на защищенные.

См. Руководство по видимости

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

Думаю, вы могли бы что-то использовать с помощью Reflection. Например, в вашем классе Spawnable:

 public function __set($name, $value) { $reflector = new ReflectionClass(get_class($this)); $prop = $reflector->getProperty($name); $prop->setAccessible(true); $prop->setValue($this, $value); } 

Однако не самый красивый код.

Рассмотрев мою концепцию, я думаю, что это плохая идея, чтобы пойти с этим подходом. Это общая проблема с отсутствием различий между свойствами и полями PHP. Конечно, частные поля никогда не должны быть доступны извне, а только свойства, которые определяются программистом. Отсутствие авто-свойств (и я не имею в виду эти магические методы __set() и __get() ) или некоторые обычные правила доступа к свойствам, затрудняет угадать, какое соглашение об именах было использовано программистом при реализации сеттеров для частных полей в своем классе.

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

Однако большое спасибо за ваши мысли и подсказки!