【发布时间】:2017-09-12 17:30:14
【问题描述】:
我正在尝试扩展一个特征。我的意思是创建一个 trait,为不同的 trait 重新定义几个方法。
这是我的代码(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 之前,如果您尝试定义相同的属性两次,特征会引发致命错误。因此,由于我在 HasTimestamps 和 ExtendHasTimestamps 中都通过 use HasTimestamps 定义了 $timestamps,所以它会中断。
简而言之:
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支持我的特质?
This question 没有回答我的问题,因为我正在尝试使用一个 trait 来覆盖另一个 trait,而不是仅仅在我需要使用此代码的每个类中添加方法。
【问题讨论】:
-
您在
ExtendHasTimestamps特征中所做的事情似乎是一个修复,您是否有可能覆盖或替换原始特征而不是提供自己的特征? -
不幸的是,它们是 Laravel 供应商文件,这意味着如果我编辑
Eloquent\Model或HasTimestamps,它将在下次运行composer update或类似文件时撤消。 -
忘记 trait 并扩展基本模型类来实现您的修复怎么样? (并使您的模型类扩展新的基类而不是 Laravel 的)
-
是的。那会奏效。我可能最终会这样做。谢谢。
-
对不起,伙计,我会提供一个完整的答案,但我没有在这里设置 Laravel 来正确测试它。这是我找到的链接laracasts.com/discuss/channels/eloquent/…