所以,这就是我的特质:
trait Cacheable
{
protected static $isCacheEnabled = false;
protected static $cacheExpirationTime = null;
public static function isCacheEnabled()
{
return static::$isCacheEnabled && Cache::isEnabled();
}
public static function getCacheExpirationTime()
{
return static::$cacheExpirationTime;
}
}
这是基类:
abstract class BaseClass extends SomeOtherBaseClass
{
use Cacheable;
...
}
这是我的最后两堂课:
class Class1 extends BaseClass
{
...
}
class Class2 extends BaseClass
{
protected static $isCacheEnabled = true;
protected static $cacheExpirationTime = 3600;
...
}
这是执行这些类的代码部分:
function baseClassRunner($baseClassName)
{
...
$output = null;
if ($baseClassName::isCacheEnabled()) {
$output = Cache::getInstance()->get('the_key');
}
if ($output === null) {
$baseClass = new $baseClassName();
$output = $baseClass->getOutput();
if ($baseClassName::isCacheEnabled()) {
Cache::getInstance()->set('the_key', $output);
}
}
...
}
此代码不起作用,因为 PHP 抱怨在 Class2 中定义与 Cacheable 中相同的属性。我无法在构造函数中设置它们,因为我想在运行构造函数之前读取它们。我对想法持开放态度,任何帮助将不胜感激。 :)
编辑:
嗯,我在几个地方使用了这个可缓存特性,所以我有点混淆了。 :) 这样就可以正常工作了。但是我有另一个类直接使用 Cacheable 特征,当我尝试在该类上执行此操作时,我收到了提到的错误。所以...假设 BaseClass 不是抽象的,并且我正在尝试在其上设置这些缓存属性。问题还是一样。
您无法重新分配特征属性。
来自 PHP 手册 http://php.net/traits
参见示例 #12 冲突解决
如果特征定义了属性,那么类就不能定义属性 具有相同的名称,否则会发出错误。它是一个 E_STRICT 如果 类定义是兼容的(相同的可见性和初始值) 否则会出现致命错误。
一种解决方案是在类中定义覆盖属性
class Class2 extends BaseClass
{
protected static $_isCacheEnabled = true;
protected static $_cacheExpirationTime = 3600;
...
}
然后修改你的特质......
trait Cacheable
{
protected static $isCacheEnabled = false;
protected static $cacheExpirationTime = null;
public static function isCacheEnabled()
{
if ( Cache::isEnabled() ) {
return isset( static::$_isCacheEnabled ) ? static::$_isCacheEnabled :
static::$isCacheEnabled;
} else {
return false;
}
}
public static function getCacheExpirationTime()
{
return isset ( static::$_cacheExpirationTime ) ? static::$_cacheExpirationTime :
static::$cacheExpirationTime;
}
}
您无法覆盖属性,但可以覆盖函数。因此,如果您要使用给定的属性而不更改它们,可能的解决方案之一可能是:
trait Cacheable {
protected static function isCacheEnabledForClass() { return false; }
public static function isCacheEnabled()
{
return static::isCacheEnabledForClass() && Cache::isEnabled();
}
}
class Class2 extends BaseClass {
protected static function isCacheEnabledForClass() { return true; }
}
你可以使用 Defined():
// only defined in classes
// static $isCacheEnabled = false;
public static function isCacheEnabled()
{
return defined(static::$isCacheEnabled ) ? static::$isCacheEnabled : false;
}
或者也许您可以接受受保护的变量而不是静态变量?
该问题已在 PHP 8.3 中修复。
使用具有静态属性的特征现在将重新声明静态 从父类继承的属性。这将创建一个 当前类的单独静态属性存储。这是 类似于直接将静态属性添加到类中,无需 特征。