Итак, это моя черта:
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; ... }
Это мои 2 заключительных класса:
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, и когда я пытаюсь сделать это в этом классе, я получаю metioned ошибку. Итак … Предположим, что 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; } }
Вы можете использовать определенные ():
// only defined in classes // static $isCacheEnabled = false; public static function isCacheEnabled() { return defined(static::$isCacheEnabled ) ? static::$isCacheEnabled : false; }
Или, может быть, вы могли бы жить с защитой переменной вместо статики?