1

Base classes(usually abstact ones) can have methods which can be tuned with overriding constants in child classes. Those contants can also have default values.

example:

abstract class BaseClass{
    const NAME = '<default name>';

    public function sayHello(){
        printf("Hello! My name is %s\n", static::NAME);
    }
}

// will use default constant value
class SomeClass extends BaseClass{}

// constant value is overridden
class OtherClass extends BaseClass{
    const NAME = 'Stephen Hawking';
}

(new SomeClass())->sayHello(); // Hello! My name is <default name>
(new OtherClass())->sayHello(); // Hello! My name is Stephen Hawking

But if I replace abstact class with trait I get

PHP Fatal error:  Traits cannot have constants in /mnt/tmpfs/1.php on line 4

So is it possible to use them in traits?

quant2016
  • 412
  • 4
  • 12

1 Answers1

0

Someone suggested to use static properties instead, but it doesn't work because of

PHP Fatal error:  OtherClass and SayTrait define the same property ($name) in the composition of OtherClass. However, the definition differs and is considered incompatible. Class was composed in /mnt/tmpfs/1.php on line 19

So possible workaroud is to use trait in parent class then extend target class from it.

trait SayTrait {
    public static $name = '<default name>';

    public function sayHello(){
        printf("Hello! My name is %s\n", static::$name);
    }
}


class SomeClass{
    use SayTrait;
}

// added as workaround.
abstract class ParentClass{
    use SayTrait;
}
// I have to move using trait to parent class to avoid Fatal Error
class OtherClass extends ParentClass {
    public static $name = 'Stephen Hawking';
}

(new SomeClass())->sayHello();
(new OtherClass())->sayHello();

Another solution is to use value hardcoded in method itself if class constant is not defined. Unfortunately, null coalescing operator (??) doesn't work with constants so I have to use defined + ternary operator(thanks to https://stackoverflow.com/a/50974262)

trait SayTrait {

    public function sayHello(){
        printf("Hello! My name is %s\n", defined('static::NAME')? static::NAME : '<default name>');
    }

}

class SomeClass{
    use SayTrait;
}

class OtherClass {
    use SayTrait;
    const NAME = 'Stephen Hawking';
}

(new SomeClass())->sayHello();
(new OtherClass())->sayHello();

quant2016
  • 412
  • 4
  • 12