11

所以,这是我的特点:

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 特性,所以我有点搞混了。:) 像这样工作得很好。但是我有另一个类直接使用 Cacheable 特征,当我尝试在该类上执行此操作时,我得到了提到的错误。所以......假设 BaseClass 不是抽象的,我正在尝试在其上设置这些缓存属性。问题还是一样的。

4

3 回答 3

7

您不能重新分配特征属性。

来自 PHP 手册http://php.net/traits

参见示例 #12 冲突解决

如果一个 trait 定义了一个属性,那么一个类不能定义一个同名的属性,否则会发出错误。如果类定义兼容(相同的可见性和初始值),则为 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;
    }
}
于 2013-12-07T04:50:29.343 回答
1

您不能覆盖属性,但可以覆盖函数。因此,如果您要使用给定的属性而不是更改它们,则可能的解决方案之一可能是:

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; }
}
于 2018-01-17T07:03:28.447 回答
0

你可以使用定义的():

// only defined in classes
// static $isCacheEnabled = false;

public static function isCacheEnabled()
{
    return defined(static::$isCacheEnabled ) ? static::$isCacheEnabled : false;
}

或者,也许您可​​以接受受保护的变量而不是静态变量?

于 2016-08-20T17:22:12.860 回答