繁体   English   中英

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

[英]PHP equivalent of enum in namespace [C/C++]

我想整齐地组织我的常数。

在C ++中,我会将枚举或变量放在命名空间(或更多)中,如下所示:

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

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

这会让我有可能像访问它们一样

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

我怎样才能在PHP中实现它?

就枚举而言:PHP中没有枚举。 你可以编写一个数组(实际上是一个HashTable),或者你必须使用一个(单独的)命名空间和/或为它定义一个类,因为枚举更接近一个类,我可能会选择对于后者并继续写下:

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

jycr753已经链接了这个问题 ,它并告诉你如何在PHP中模仿枚举,但如果你问我,这只是把它那一点点太远 使用ReflectionClass只是为了模拟一个缺失的构造就像修改你的汽车所以它可以兼作摩托车。

在名称空间上:
PHP中的命名空间相对“新” ,并且它们不是100%等同于C ++命名空间。 首先,它们不能以您尝试的方式嵌套。 为此,您将不得不求助于在给定命名空间内声明类,并接受只允许1个额外级别。
所有事情都有所帮助,我认为你正在寻找这样的东西:

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

global_const.php文件定义全局常量,如下所示:

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

结果输出是:

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

当然,在现实中,你的代码将被扩出过多个文件,而且往往不是,你只能使用一个命名空间该文件,并use其他名称空间(≃ using在C ++中):

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

PHP命名空间系统中的不一致性已有详细记录(谷歌搜索它们)。 但是举个例子,如果我用上面的语句启动我的文件,可以使用以下语句:

$myVar = Foo\SOME_CONSTANT;

解决了

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

但是,如果我要删除use Foo ,相同的语句将解析为:

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

现在,似乎完全合理的,但同样的规则并不适用于核心功能: \\str_replacestr_replace都正确解决,唯一的区别是,后者将首先执行一个函数调用查找str_replace在当前名字空间,然后回退到全局命名空间。
好吧,有了一些“善意”你可以说这也是相当可预测的行为。 可悲的是,奇怪的或恶意的,PHP 不会以同样的方式使用它的核心对象 (如行为时DateTimestdClassExceptionPDO ...)。
mysqli_*扩展名为例:您可以在所有命名空间中使用其过程API,并且是一个快乐的露营者,但如果您更喜欢OO API,则必须使用use语句,或者每当您添加反斜杠时写new \\mysqli()

好的,所以PHP有它的缺点,当然,我们都知道这么多,至于你的问题,我相信我现在有一个答案,而且对我来说,继续这种咆哮将是完全没有意义的。 有关名称空间的所有信息都可以在手册BTW中找到

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM