有一个存储库,它有一种为更改准备数据的方法
class Repository
{
protected function prepareSaveData($data, $id = null)
{
return $data;
}
}
并且有 2 个特征覆盖了此方法(您无法阅读它们的作用,它们只是存在并覆盖了该方法)
trait DatedTrait
{
protected function prepareSaveData($data, $id = null) {
if ($id) {
if (array_search('date_update', $this->fields) && !($data['date_update'] ?? null)) {
$data['date_update'] = date('Y-m-d H:i:s');
}
} else {
if (array_search('date_create', $this->fields) && !($data['date_create'] ?? null)) {
$data['date_create'] = date('Y-m-d H:i:s');
}
}
return parent::prepareSaveData($data, $id);
}
}
trait OptionsTrait
{
protected function prepareSaveData(
$data,
$id = null
) {
$options = [];
if ($id) {
$item = $this->getItem($id);
if ($item) {
$options = json_decode($item['options'], true) ?: [];
}
}
foreach ($this->optionsFields as $fieldname) {
if (isset($data[$fieldname])) {
$options[$fieldname] = $data[$fieldname];
}
}
$data['options'] = json_encode($options);
return parent::prepareSaveData($data, $id);
}
}
一些代表需要 DatedTrait,一些 OptionsTrait,但一个萝卜需要它们两者,我不能同时使用它们。
这就是我要做的:
class ConcreteRepository extends Repository
{
use OptionsTrait {
prepareSaveData as prepareOptionsSaveData;
}
use DatedTrait {
prepareSaveData as prepareDatedSaveData;
}
protected function prepareSaveData(
$data,
$id = null
) {
$data = $this->prepareDatedSaveData($data, $id);
$data = $this->prepareOptionsSaveData($data, $id);
return parent::prepareSaveData($data, $id);
}
}
但是在这种情况下,只有第一个连接的特征起作用,第二个的方法没有被调用,甚至没有通知。请告诉我,如何解决这个问题?
选择 PS Traits 是因为 您不能使用多重继承,以免生成 DatedRepository、OptionsRepository、DatedOptionsRepository、DatedOptionsExtraFeatureRepository 等类...
船长显然推荐了一个装饰器:我们创建了 2 个类,每个类都有一个 trait 和一个装饰器类,这些类的对象被转移到
正如@teran 建议的那样,我们需要将特征连接结构更改为: