两个库在trait中分别提供一个方法,该方法可以覆盖默认的基类方法。
// This is a Framework base class
class Model {
function getAttribute($key) {
return "Model->$key";
}
}
// This is a trait from library A which provides extra stuff
trait HasUuid {
function getAttribute($key) {
if ($key==='uuid') return "HasUuid->$key";
return parent::getAttribute($key);
}
}
// This is a trait from library B which provides extra stuff
trait HasQuantity {
function getAttribute($key) {
if ($key==='quantity') return "HasQuantity->$key";
return parent::getAttribute($key);
}
}
现在,我的应用程序中有一个继承自Model
的类,需要同时使用这两个特征。
PHP允许别名特征函数,以解决库之间的命名冲突。所以这就是我的最终目的:
class Product extends Model {
use HasUuid { getAttribute as getHasUuidAttribute; }
use HasQuantity { getAttribute as getHasQuantityAttribute; }
function getAttribute($key) {
// Framework default value to use as fallback
$parentValue = parent::getAttribute($key);
$overrides = ['getHasUuidAttribute', 'getHasQuantityAttribute',];
foreach ($overrides as $override)
{
$overriddenValue = $this->$override($key);
// A trait has some better value than the fallback
if ($overriddenValue !== $parentValue) return $overriddenValue;
}
// Nothing better, use fallback from framework
return $parentValue;
}
}
我们最终遇到了递归问题:调用覆盖的trait方法时,它们引用parent::getAttribute
方法,该方法触发另一个对Product::getAttribute
的调用,该调用无限递归。
如何通过保留对两个特征的访问来解决此递归问题?
当然,由于每个特征都来自库,因此我无法更改其代码。
答案 0 :(得分:2)
您可以利用private
关键字将这些内容设为私有。
class Product extends Model {
use HasUuid { getAttribute as private getHasUuidAttribute; }
use HasQuantity { getAttribute as private getHasQuantityAttribute; }
function getAttribute($key) {
// Framework default value to use as fallback
$parentValue = parent::getAttribute($key);
$overrides = ['getHasUuidAttribute', 'getHasQuantityAttribute',];
foreach ($overrides as $override)
{
$overriddenValue = $this->$override($key);
// A trait has some better value than the fallback
if ($overriddenValue !== $parentValue) return $overriddenValue;
}
// Nothing better, use fallback from framework
return $parentValue;
}
}
希望这会有所帮助。