Как инициализировать свойства типа Объект в 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);
Есть какой-нибудь вариант сделать что-то подобное сейчас или, если нет, ожидается ли концепция подобного в будущем, где-нибудь в седьмой версии?

21 Авг 2019 в 07:05
228 +1
0
Ответы
1

В PHP нельзя инициализировать свойства типа объект в трейтах, как вы пытаетесь сделать. Однако, вы можете использовать метод инициализации, как вы уже сделали в вашем примере.

Что касается возможности регистрации нескольких construct методов в очередь, такого функционала в PHP нет. construct метод может быть только один в классе.

Если вам не нравится инициализация объекта при каждом вызове метода, то вы можете воспользоваться singleton паттерном или использовать зависимость инъекций для передачи объекта в трейт.

Что касается вашей идеи с регистрацией мнемоник для вызова методов трейта из параметров, это можно реализовать через динамический вызов методов с помощью call_user_func_array или через магический метод __call в вашем трейте.

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

20 Апр 2024 в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир