PHP Trait 属性冲突: [Class] and [Trait] define the same property in the composition of [Class]

Illuminate\Database\Eloquent\Model;          // 业务表基类
Illuminate\Database\Eloquent\Relations\Pivot;// 关联中间表基类

最近在设计新项目的Laravel Model时,因为业务表Dao与关联表Dao采用了不同的基类,我们希望拥有一个共同的父类进行Dao层的统一封装,遂建立了所有的Dao共用的Trait.

// 公用Trait
trait Common
{
    public $keyType = 'bigint';
}
// 业务表Dao基类
class Base extends Model
{
    use Common;
}

很不幸的是,这样出现了Fatal Error.

Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_UNKNOWN)
Illuminate\Database\Eloquent\Model and App\Models\Traits\Common define the same property ($keyType) in the composition of App\Models\Base. However, the definition differs and is considered incompatible. Class was composed

查看官方文档(http://www.php.net/manual/zh/language.oop5.traits.php),官方有解释:

Trait 定义了一个属性后,类就不能定义同样名称的属性,否则会产生 fatal error。 有种情况例外:属性是兼容的(同样的访问可见度、初始默认值)。 在 PHP 7.0 之前,属性是兼容的,则会有 E_STRICT 的提醒。

需要注意的是,trait的属性与方法不同,不能通过trait直接重写基类,trait中的属性可见度、默认值都必须与继承它的类相同。 简单的例子:

class Model
{
	public $key = 'a';
}
trait Common
{
	public $key = 'b';
}
class Node extends Model
{
	use Common;
	public function output()
	{
		echo $this->key . "\n";
	}
}
$node = new Node();
$node->output(); // fatal error

这样会抛出致命错误,如果我们修改Node类加入对$this->key 的定义,并与trait Common一致,则冲突被解决。

class Node extends Model
{
	use Common;
	public $key = 'b';
	public function output()
	{
		echo $this->key . "\n";
	}
}

综上所述,trait无法直接通过覆盖属性的方式修改基类属性,可以考虑通过构造函数加入调用trait中的初始化方法来解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值