Расширение черты конфликтует с самим собой

Я пытаюсь расширить черту. Под этим я подразумеваю создание черты, которая переопределяет несколько методов для другой черты.

Это мой код (PHP 5.6 и Laravel 5.4):

namespace App\Traits;

use Illuminate\Database\Eloquent\Concerns\HasTimestamps;

trait ExtendHasTimestamps
{
use HasTimestamps {
HasTimestamps::setCreatedAt as parentSetCreatedAt;
HasTimestamps::setUpdatedAt as parentSetUpdatedAt;
}

public function setCreatedAt($value) {
if ($value !== '') return $this;
return $this->parentSetCreatedAt($value);
}

public function setUpdatedAt($value) {
if ($value !== '') return $this;
return $this->parentSetUpdatedAt($value);
}
}

Проблема возникает, когда я использую ExtendHasTimestamps в модели это противоречит HasTimestamps так как Eloquent\Model имеет use HasTimestamps, До PHP 7 черты выдают фатальную ошибку, если вы пытаетесь определить одно и то же свойство дважды. Так как я определяю $timestamps оба в HasTimestamps и снова через ExtendHasTimestamps благодаря use HasTimestamps, это ломает.

Короче:

trait HasTimestamps {
protected $timestamps = true; //problematic property
}

trait ExtendHasTimestamps {
use HasTimestamps;
// add validation then call HasTimestamps method
}

class Model {
use HasTimestamps;
}

class MyModel extends Model {
use ExtendHasTimestamps; //everything breaks
}

Есть ли способ убедить PHP в том, что это действительно одно и то же и может перестать конфликтовать с самим собой, или сообщить классу, с которым я работаю (расширение Eloquent\Model) прекратить использование HasTimestamps в пользу моей черты?


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

2

Решение

Мне кажется, что вам не нужно расширять черту в первую очередь. Я просто переопределил бы методы в признаке, используемом в вашем дочернем классе, а затем вызвал бы parent методы внутри черты.

Демо-версия: https://3v4l.org/2DqZQ

<?php

trait HasTimestamps
{
protected $timestamps = true;

public function setCreatedAt($value)
{
echo 'HasTimestamps::setCreatedAt'.PHP_EOL;
return $this;
}

public function setUpdatedAt($value)
{
echo 'HasTimestamps::setUpdatedAt'.PHP_EOL;
return $this;
}
}

trait ExtendHasTimestamps
{
public function setCreatedAt($value)
{
echo 'ExtendHasTimestamps::setCreatedAt'.PHP_EOL;

if ($value !== '') return $this;

return parent::setCreatedAt($value);
}

public function setUpdatedAt($value)
{
echo 'ExtendHasTimestamps::setUpdatedAt'.PHP_EOL;

if ($value !== '') return $this;

return parent::setUpdatedAt($value);
}
}

class Model
{
use HasTimestamps;
}

class MyModel extends Model
{
use ExtendHasTimestamps;
}

(new MyModel)->setCreatedAt('');

echo PHP_EOL;

(new MyModel)->setCreatedAt('time');

ExtendHasTimestamps :: setCreatedAt
HasTimestamps :: setCreatedAt

ExtendHasTimestamps :: setCreatedAt

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector