Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP traits - defining generic constants

Tags:

oop

php

traits

What is the best way to define constants that may be used by a number of classes within a namespace? I'm trying to avoid too much inheritance, so extending base classes is not an ideal solution, and I'm struggling to find a good solution using traits. Is this in any way possible in PHP 5.4 or should a different approach be taken?

I have the following situation:

trait Base {     // Generic functions }  class A  {     use Base; }  class B  {     use Base; } 

The problem is that it is not possible to define constants in PHP traits. Ideally, I would want something like the following:

trait Base {     const SOME_CONST = 'someconst';     const SOME_OTHER_CONST = 'someotherconst';      // Generic functions } 

Then these could be accessed though the class that applies the trait:

echo A::SOME_CONST; echo B::SOME_OTHER_CONST; 

But due to the limitations of traits this isn't possible. Any ideas?

like image 900
Tom Jowitt Avatar asked Jun 23 '14 03:06

Tom Jowitt


People also ask

What is a correct way of defining constants in PHP?

A constant is an identifier (name) for a simple value. The value cannot be changed during the script. A valid constant name starts with a letter or underscore (no $ sign before the constant name). Note: Unlike variables, constants are automatically global across the entire script.

Can traits have constants?

You can't use constants in a Trait.

Can PHP traits have variables?

Traits can define static variables, static methods and static properties. Note: As of PHP 8.1. 0, calling a static method, or accessing a static property directly on a trait is deprecated.

Can PHP traits have properties?

Traits can have properties and methods with private and protected visibility too. You can access them like they belong to class itself. There is no difference.


2 Answers

I ended up using user sectus's suggestion of interfaces as it feels like the least-problematic way of handling this. Using an interface to store constants rather than API contracts has a bad smell about it though so maybe this issue is more about OO design than trait implementation.

interface Definition {     const SOME_CONST = 'someconst';     const SOME_OTHER_CONST = 'someotherconst'; }  trait Base {     // Generic functions }  class A implements Definition {     use Base; }  class B implements Definition {     use Base; } 

Which allows for:

A::SOME_CONST; B::SOME_CONST; 
like image 115
Tom Jowitt Avatar answered Sep 20 '22 10:09

Tom Jowitt


You could also use static variables. They can be used in the class or the trait itself. - Works fine for me as a replacement for const.

trait myTrait {     static $someVarA = "my specific content";     static $someVarB = "my second specific content"; }  class myCustomClass {     use myTrait;      public function hello()     {         return self::$someVarA;     } } 
like image 22
Michael Avatar answered Sep 21 '22 10:09

Michael