Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP traits - change value of static property in inherited class

So, this is my trait:

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;
    }
}

This is the base class:

abstract class BaseClass extends SomeOtherBaseClass
{
    use Cacheable;
    ...
}

These are my 2 final classes:

class Class1 extends BaseClass
{
    ...
}

class Class2 extends BaseClass
{
    protected static $isCacheEnabled = true;
    protected static $cacheExpirationTime = 3600;
    ...
}

Here is the part of the code which executes these classes:

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);
        }
    }
    ...
}

This code doesn't work because PHP complains about defining same properties in Class2 as in Cacheable. I can't set them in their constructors because I want to read them even before running the constructor. I'm open for ideas, any help would be appreciated. :)

EDIT:

Well, I use this Cacheable trait on several places so i kind of got mixed up. :) This works fine like this. But I have another class which directly uses the Cacheable trait and when I try to do this on that class, I get the metioned error. So... Just assume that the BaseClass isn't abstract and I'm trying to set these cache properties on it. The question remains the same.

like image 474
morgoth84 Avatar asked Nov 30 '13 10:11

morgoth84


People also ask

Can we change static variable value in PHP?

No. Static can be used to declare class variables or within function to declare a variable which persists over function calls, but not over executions of the script.

Can traits be inherited PHP?

In PHP, a trait is a way to enable developers to reuse methods of independent classes that exist in different inheritance hierarchies. Simply put, traits allow you to create desirable methods in a class setting, using the trait keyword. You can then inherit this class through the use keyword.

Can static methods be inherited in PHP?

The static variable is used in the A and B classes, yet the method is inherited so it is actually the same code which is called. Until PHP 8.0, there would be a distinct static variable depending on which class is called.

How use $this in static method in PHP?

You can't use $this inside a static function, because static functions are independent of any instantiated object. Try making the function not static. Edit: By definition, static methods can be called without any instantiated object, and thus there is no meaningful use of $this inside a static method.


1 Answers

You can not reassign trait properties.

From PHP manual http://php.net/traits

See Example #12 Conflict Resolution

If a trait defines a property then a class can not define a property with the same name, otherwise an error is issued. It is an E_STRICT if the class definition is compatible (same visibility and initial value) or fatal error otherwise.

One solution would be to define override properties in the class

class Class2 extends BaseClass
{
    protected static $_isCacheEnabled = true;
    protected static $_cacheExpirationTime = 3600;
    ...
}

and then modify your trait as such...

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;
    }
}
like image 89
Tariq C Avatar answered Sep 20 '22 09:09

Tariq C