Прежде всего, я не хочу расширять класс. В идеале я бы хотел сделать это.
public function __construct() { /* Set Framework Variable */ global $Five; $this =& $Five; }
У меня есть система, в которой переменная $ Five является классом контейнера, который содержит другие библиотеки. Я мог бы назначить это локальной переменной Five … ie
public function __construct() { /* Set Framework Variable */ global $Five; $this->Five = $Five; }
Однако причина, по которой я пытаюсь избежать этого, заключается в том, что вызовы функций будут немного длинными.
$this->Five->load->library('library_name');
Это немного уродливо. Намного лучше.
$this->load->library('library_name');
Какое лучшее решение для этого?
я думаю что
$this->Five->load->library('library_name');
будет вашим лучшим вариантом, если вы не решите, что класс расширяет вспомогательный класс. AKA
class Something extends Helper_Class
Однако это означает, что Helper_Class
каждый раз при создании экземпляра класса.
Другим методом было бы иметь псевдостатический класс, который присваивал бы всем вспомогательным классам членам класса
public function setGlobals($five) { $this->loader = $five->loader; }
Тогда просто позвоните
public function __construct($five) { someClass::setGlobals($five); }
Если $Five
является глобальным, вы могли бы просто global $Five
каждый раз, когда вы захотите его использовать, но включение в верхнюю часть каждой функции просто похоже на плохое кодирование.
Кроме того, я хотел бы сделать объявление публичной службы о том, что глобальные переменные, как правило, представляют собой плохую идею, и вы можете искать «Инъекция зависимостей» или альтернативу глобальным переменным. AKA
public function __construct($five);
вместо
global $five;
Глобалы полагаются на внешнюю переменную, которая должна присутствовать и уже установлена, в то время как инъекция зависимостей запрашивает переменную, которую предполагается считать экземпляром класса Five.
Если вы используете PHP 5.1 (спасибо Gordon), вы можете застраховать переменную как экземпляр FiveClass
, выполнив следующее:
public function__construct(FiveClass $five);
$ это ссылка на текущий экземпляр класса, который вы определяете. Я не думаю, что вы можете назначить его. Если Five является глобальным, вы должны просто сделать это:
$Five->load->library('library_name');
Вы можете пойти с какой-то реализацией шаблона инъекции зависимостей:
Инъекционная инъекция (DI) в компьютерном программировании относится к процессу подачи внешней зависимости к программному компоненту. Это конкретная форма инверсии управления, в которой инвертированное беспокойство является процессом получения необходимой зависимости.
См. Также документацию для контейнера symfony DI . Я могу очень рекомендовать эту реализацию контейнера DI, если вы хотите улучшить способ обработки ваших «глобальных».
Вы также можете прочитать этот вопрос о «лучших способах доступа к глобальным объектам».
Как насчет создания соответствующих элементов данных и методов из пяти статических членов класса? Эта
$this->Five->load->library('library_name');
станет
Five::load->library('library_name');
и вам не пришлось бы проходить & $ 5 вокруг.
Вы не можете перезаписать $ this (например, на C ++), но вы можете легко построить агрегат с помощью __call () для вызовов методов и __get (), __set (), __isset () для свойств.
Пример для __call ():
class Five { public function bar() { echo __METHOD__, " invoked\n"; } } class Foo { protected $Five = null; public function __construct(Five $five=null) { if ( is_object($five) ) { $this->Five = $five; } } public function __call($name, $args) { // there's no accessible method {$name} in the call context // let's see if there is one for the object stored in $five // and if there is, call it. $ctx = array($this->Five, $name); if ( !is_null($this->Five) && is_callable($ctx) ) { return call_user_func_array($ctx, $args); } else { // .... } } } $foo = new Foo(new Five); $foo->bar();
prints Вызывается Five::bar invoked
.
По моему мнению, самый большой недостаток заключается в том, что гораздо труднее увидеть «со стороны», на что способен объект.
Я уверен, что вы не можете переназначить $this
, так как это одна из тех особых вещей, которая выглядит как переменная в PHP, но обрабатывается немного по-разному за кулисами.
Если ваши проблемы связаны с семантикой вашего метода, вызвавшего слишком длинный, я бы сделал load
вызова метода вместо свойства объекта
$this->load()->library('library_name'); public function load() { return $this->Five; }
может быть, лучше для вас использовать PHP Magic Methods? http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods