PHP-черты – определение общих констант

Каков наилучший способ определения констант, которые могут использоваться рядом классов в пространстве имен? Я стараюсь избегать слишком большого наследования, поэтому расширение базовых классов не является идеальным решением, и я изо всех сил пытаюсь найти хорошее решение, используя черты. Является ли это любым возможным способом в PHP 5.4 или должен быть принят другой подход?

У меня есть следующая ситуация:

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

Проблема в том, что невозможно определить константы в чертах PHP. В идеале, что бы я хотел, это примерно следующее:

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

Затем они могут быть доступны, хотя класс, который применяет свойство:

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

Но из-за ограничений черт это невозможно. Есть идеи? Благодарю.

Я закончил использование @sectus предложений интерфейсов, поскольку он чувствует себя наименее проблематичным способом справиться с этим. Использование интерфейса для хранения констант, а не контрактов API имеет плохой запах, хотя, возможно, эта проблема больше связана с дизайном OO, чем с реализацией признака. Я все еще не очень доволен этим решением, поэтому не буду принимать ответ на некоторое время, если у кого-то есть лучшее предложение.

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

Это позволяет:

 A::SOME_CONST; B::SOME_CONST; 

Вы также можете использовать статические переменные. Они могут использоваться в классе или самом признаке. – Прекрасно работает для меня в качестве замены для const.

 trait myTrait { static $someVarA = "my specific content"; static $someVarB = "my second specific content"; } class myCustomClass { use myTrait; public function hello() { return self::$someVarA; } } 

Чтобы ограничить объем ваших констант, вы можете определить их внутри пространства имен:

 namespace Test; const Foo = 123; // generic functions or classes echo Foo; echo namespace\Foo; 

Недостатком такого подхода является то, что автозагрузка не будет работать для констант, по крайней мере, не для 5.4; типичным способом этого является обертывание этих констант в статическом классе, то есть:

 namespace Test; class Bar { const Foo = 123; } 

есть немного хакерский способ сделать это, определив константу, а затем вернув эту константу с вашими характеристическими функциями:

 define ('myConst','this is a constant'); trait Base { public function returnConst() { return myConst; } } class myClass { use Base; } $o = new myClass(); echo $o->returnConst(); 

Что-то еще, чтобы рассмотреть, может ли вы вместо этого использовать абстрактный класс, а затем наследовать.

 abstract class Base { const A = 1; const B = 2; } class Class1 extends Base {} class Class2 extends Base {} echo Class1::A; echo Class2::B; 

Конечно, часть причин для признаков заключается в замене сложных деревьев наследования композицией. Зависит от ситуации.

Ничего хорошего, но, может быть …

 trait Base { public static function SOME_CONST() { return 'value1'; } public static function SOME_OTHER_CONST() { return 'value2'; } // generic functions } class A { use Base; } class B { use Base; } echo A::SOME_CONST(); echo B::SOME_OTHER_CONST();