Как инициализировать свойства типа Объект в trait'ах PHP или существует ли возможность регистрации нескольких __construct методов в очередь? Пытался задать вопрос на stackoverflow, но, видимо, из-за корявого английского меня там не поняли. Мне нужно инициализировать свойство трейта как экземпляр соседнего класса.trait FilterTrait { protected $_filter = new Filter(); // Нельзя использовать как дефолтное значение public function __construct () { // Перезапишется в используемом классе $this->_filter = new Filter(); } public function SetFilter ($arFilter) { $this->_filter->Set($arFilter); } public function CleanFilter () { $this->_filter->CLean(); } public function GetFilter () { return $this->_filter->Get(); } ... } Не хочу, чтобы дочерний класс помогал в работе используемого трейта, и вообще знал что-то об его устройстве, вот так:class Select extends Query { use TablesListTrait, FieldsListTrait, FilterTrait, HavingTrait, SortTrait, LimitTrait, GroupTrait; function __construct () { $this->_tablesList = new TablesList(); $this->_fieldsList = new FieldsList(); $this->_filter = new Filter(); ... } ... } И инициализировать при каждом вызове метода тоже не хочуtrait FilterTrait { protected $_filter; public function InitializeFilter () { if (is_null($this->_filter)) { $this->_filter = new Filter(); } } public function SetFilter ($arFilter) { $this->InitializeFilter(); $this->_filter->Set($arFilter); } public function CleanFilter () { $this->InitializeFilter(); $this->_filter->CLean(); } public function GetFilter () { $this->InitializeFilter(); return $this->_filter->Get(); } } Можно, конечно, замутить перезагрузку методов, но это не сильно лучше. Нашел информацию о том, что в версии 5.6 вот такое написание поддерживаетсяclass Foo { protected $bar = new Baz(); } не проверял, но все-таки большинство хостингов на данный момент стоят на 5.3 - 5.4, и использовать эти фишки пока сложно. К тому же хочу еще реализовать регистрацию мнемоник для вызова методов трейта из параметров, передающихся в дочерние классы. Если бы существовал какой-нибудь магический метод, регистрирующий несколько __construct функций, мне бы это помогло:trait Actions { protected $_arActions = array(); public function RegisterActions ($arActions) { $this->_arActions = array_merge($this->_arActions, $arActions); } public function ResetParameters ($arParameters) { foreach ($arParameters as $mnemonic => $actionParameters) { if (isset($this->_arActions[$mnemonic])) { $action = $this->_arActions[$mnemonic]; $this->$action($actionParameters); } } } } trait FilterTrait { use Actions;
public function __onUse () { $arActions = array( "filter" => "SetFilter" ); $this->RegisterActions($arActions); }
public function SetFilter ($arFilter) {...} } class Select extends Query { use TablesListTrait, FieldsListTrait, FilterTrait, HavingTrait, SortTrait, LimitTrait, GroupTrait;
public function __construct ($arParams) { $this->ResetParameters($arParams); } } ... $arSelectParams = array( "table" => "products", "fields" => array( "id", "name", "price" ), "filter" => array( "id" => 5, " 1000 ), "sort" => array( "price" => "asc" ) ); $query = new Select($arSelectParams); Есть какой-нибудь вариант сделать что-то подобное сейчас или, если нет, ожидается ли концепция подобного в будущем, где-нибудь в седьмой версии?
В PHP нельзя инициализировать свойства типа объект в трейтах, как вы пытаетесь сделать. Однако, вы можете использовать метод инициализации, как вы уже сделали в вашем примере.
Что касается возможности регистрации нескольких construct методов в очередь, такого функционала в PHP нет. construct метод может быть только один в классе.
Если вам не нравится инициализация объекта при каждом вызове метода, то вы можете воспользоваться singleton паттерном или использовать зависимость инъекций для передачи объекта в трейт.
Что касается вашей идеи с регистрацией мнемоник для вызова методов трейта из параметров, это можно реализовать через динамический вызов методов с помощью call_user_func_array или через магический метод __call в вашем трейте.
Насчет ожидания подобной концепции в будущих версиях PHP, это сложно предсказать. Но вы можете предложить свою идею на официальном сайте PHP или на форуме PHP, возможно она будет учтена в будущих версиях.
В PHP нельзя инициализировать свойства типа объект в трейтах, как вы пытаетесь сделать. Однако, вы можете использовать метод инициализации, как вы уже сделали в вашем примере.
Что касается возможности регистрации нескольких construct методов в очередь, такого функционала в PHP нет. construct метод может быть только один в классе.
Если вам не нравится инициализация объекта при каждом вызове метода, то вы можете воспользоваться singleton паттерном или использовать зависимость инъекций для передачи объекта в трейт.
Что касается вашей идеи с регистрацией мнемоник для вызова методов трейта из параметров, это можно реализовать через динамический вызов методов с помощью call_user_func_array или через магический метод __call в вашем трейте.
Насчет ожидания подобной концепции в будущих версиях PHP, это сложно предсказать. Но вы можете предложить свою идею на официальном сайте PHP или на форуме PHP, возможно она будет учтена в будущих версиях.