PHP traits - defining generic constants

孤街醉人 提交于 2019-11-26 19:26:11

问题


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?


回答1:


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;



回答2:


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



回答3:


To limit the scope of your constants, you can define them inside a namespace:

namespace Test;

const Foo = 123;

// generic functions or classes

echo Foo;
echo namespace\Foo;

A downside of this approach is that autoloading won't work for constants, at least not for 5.4; the typical way around this is to wrap those constants in a static class, i.e.:

namespace Test;

class Bar
{
    const Foo = 123;
}



回答4:


Not a good one, but maybe...

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();



回答5:


Something else to consider is whether or not you can use an abstract class instead, and then inherit.

abstract class Base
{
    const A = 1;
    const B = 2;
}

class Class1 extends Base {}
class Class2 extends Base {}

echo Class1::A;
echo Class2::B;

Of course, part of the reason for traits is replace complex inheritance trees with composition. Depends on the situation.



来源:https://stackoverflow.com/questions/24357985/php-traits-defining-generic-constants

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!