dongpu6141 2014-03-11 11:52
浏览 27
已采纳

PHP等效于命名空间中的枚举[C / C ++]

I'd like to organize my constants neatly.

In C++ I would've put enums or variables in a namespace (or more) like so:

namespace foo
{
    namespace bar
    {
        enum herp { derp, sherp, sheep };
    }

    namespace Family
    {
        const string mom  = "Anita";
        const string son  = "Bob";
        const string daughter = "Alice";
    }
}

This would give me the possibility to access them like

int x = foo::bar::derp;
string nameOfMom = foo::Family::mom;
string nameOfSon = foo::Family::son;

How can I implement this in PHP?

  • 写回答

1条回答 默认 最新

  • douhuan3420 2014-03-11 13:05
    关注

    As far as the enum is concerned: There is no enum in PHP. You can write an array (which is in fact a HashTable underneath) or you'll have to use a (separate) namespace and/or define a class for that, given that an enum is closer to a class, I'd probably opt for the latter and go ahead and write:

    class FakeEnum
    {
        const DERP = 0;
        const SHERP = 1;
        const SHEEP = 2;
    }
    

    jycr753 already linked this question, and it does show how you could emulate enums in PHP, but if you ask me, that's just taking it that little bit too far. Using a ReflectionClass just to emulate a missing construct is like modifying your car so it can double as a motorcycle.

    On to the namespaces:
    Namespaces in PHP are relatively "new", and they are not 100% equivalent to C++ namespaces. For one, they can't be nested in the way you are trying. For that, you'll have to resort to declaring classes inside a given namespace, and accept that only allows for 1 additional level.
    All things asside, I take it you're looking for something like this:

    namespace Foo
    {
        const FOOBAR = 123;
    }
    namespace Bar
    {
        const FOOBAR = 456;
    }
    namespace Work
    {
        const FOOBAR = __NAMESPACE__;
        include 'global_const.php';
        echo 'Global FOOBAR const is: ', \FOOBAR, PHP_EOL,
            'Foo::FOOBAR is: ', \Foo\FOOBAR, PHP_EOL,
            'Bar::FOOBAR is: ', \Bar\FOOBAR, PHP_EOL,
            'Work::FOOBAR is: ', FOOBAR, PHP_EOL;
    }
    

    Where the global_const.php file defines a global constant like so:

    define('FOOBAR', 'global');//just to be consistent ;-P
    

    The resulting output is:

    Global FOOBAR const is: global
    Foo::FOOBAR is: 123
    Bar::FOOBAR is: 456
    Work::FOOBAR is: Work
    

    Of course, in reality, your code will be spread-out over multiple files, and more often than not, you'll only use a single namespace for that file, and use other namespaces (≃ using in C++):

    namespace My\Core\Components\Output;
    use Foo,
        Bar,
        My\Core\Components\Input as CoreInput;
    use External\Component\Input as HelperInput;
    

    The inconsistencies in the PHP namespacing system are well documented (google search them). But to give you an example, if I start my file with the statements above, the following statement:

    $myVar = Foo\SOME_CONSTANT;
    

    resolves to

    global namespace (\ for short)
        ->Foo namespace
            -> SOME_CONSTANT
    

    But if I were to remove the use Foo, the same statement resolves to:

    \
      -> My
         -> Core
             -> Components
                 -> Output
                    -> Foo
                       -> SOME_CONSTANT
    

    Now that may seem perfectly reasonable, but the same rule does not apply to the core functions: \str_replace or str_replace are both resolved correctly, the only difference is that the latter will first perform a lookup for a function called str_replace in the current namespace, to then fall-back to the global namespace.
    Ok, with some "goodwill" you could argue that this, too, is fairly predictable behaviour. Sadly, strangely or maliciously, PHP does not behave in the same way when using its core objects (like DateTime, stdClass, Exception or PDO...).
    Take the mysqli_* extension, for example: you can use its procedural API throughout all of your namespaces and be a happy camper, but if you prefer the OO API, you'll have to use the use statements, or add a backslash whenever you write new \mysqli().

    Ok, so PHP has its faults, but of course, we all know that much, as for your question, I believe I you have an answer now, and for me to continue this rant would be utterly pointless. Everything you need to know about namespaces can be found in the manual, BTW

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Stata 面板数据模型选择
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用