Можете ли вы объяснить, как работает контроллер Zend's Action? - PullRequest
2 голосов
/ 30 марта 2011

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

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

class Parent {
    var $data = array();
    public function __construct( OtherClass $otherClass ) {
        $this->data = $otherClass->getData(); //contains some => thing
        $this->init($otherClass->getClassName());
    }
    public function init( $className ) {
        new $className; //new Child
    }
    public function __get( $name ) {
        return array_key_exists($name, $this->data) ? $this->data[$name] : null;
    }
}

class Child extends Parent {
    public function __construct() {
        echo $this->some; //won't return 'thing';
    }
}

fireeyedboy мне очень помог (спасибо) и указал Zend_Controller_Action делает то, что я хочу, но я не могу понять как они это делают?


Оригинальный вопрос

Я знаю, что здесь были подобные вопросы, но я не могу их выбросить. Также я знаю, что могу полностью изменить весь процесс, чтобы сначала инициализировать Child, а затем позвонить parent::__construct, но мне это кажется нежелательным. Как мне легко получить доступ к Parent переменным в моем случае?

Обновление:

Позвольте мне немного уточнить. Child - произвольный контроллер. Parent является матерью всех контролеров. Многие фреймворки делают то же самое, но контроллеры могут использовать переменные, методы или объекты своих родительских контроллеров, не вызывая parent::__construct (и, следовательно, заполняя конструкторы дочерних классов ненужными аргументами). Мне не нравится переписывать какие-либо из этих платформ, но я хотел бы понять, как они работают.

Ответы [ 3 ]

5 голосов
/ 30 марта 2011

Ваш дочерний класс не вызывает родительский конструктор. Вот исправление:

class Child extends Parent {
   public function __construct() {
       parent::__construct();
       echo $this->some;
   }
}

Обновление: Конструкторы родительских классов не вызываются автоматически в PHP. См. документацию :

Примечание: родительские конструкторы не являются вызывается неявно, если дочерний класс определяет конструктор. Для того, чтобы бежать родительский конструктор, вызов parent :: __ construct () внутри дочернего элемента требуется конструктор.

Так что то, что вы просите, не происходит Либо вы неверно истолковали структуру классов, либо как они работают. Обратите внимание, что PHP также поддерживает устаревшие имена конструкторов (по крайней мере до 5.3.3): если в классе нет метода __construct (), PHP предполагает, что конструктор назван в честь класса (т. Е. Class Foo {function Foo () {} ) обрабатывает метод Foo () как конструктор).

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

Внедрение НИЧЕГО с использованием конструкции контроллера, как правило, ПЛОХАЯ ПРАКТИКА !Проблема заключается в вашем дизайне.Какой тип объекта OtherClass?Это адаптер БД?Это ACL?Это какой-то вспомогательный класс?

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

Вы НИКОГДА не должны использовать __construct () для выполнения какой-либо грязной работы.Для этого используется init ().Но у него нет параметров.И есть причина для этого - опять же - вы не должны вводить зависимости, подобные этой;)

Обновление: Обратите внимание, что ваш класс использует обескураженный синтаксис определения переменной члена PHP4.Попробуйте заменить var на protected.

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

Проблема в том, что ваш класс Child не вызывает базовый конструктор.

Кстати, Parent не является допустимым именем класса в PHP.Я изменил имена классов для ясности.См. Ниже:

class ChildClass extends ParentClass {
   public function __construct() {
       parent::__construct(/* what goes here? */);
       echo $this->some;
   }
}

Однако обратите внимание на часть what goes here?: ваш базовый класс требует ссылку на экземпляр OtherClass, который должен быть создан.Следовательно, поскольку ChildClass IS-A ParentClass, ему также необходимо каким-то образом получить такой экземпляр.Вам нужно будет либо добавить параметр в ChildClass::__construct и переслать значение в parent::__construct, либо как-то самостоятельно определить значение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...