【问题标题】:PHP equivalent of enum in namespace [C/C++]命名空间中枚举的 PHP 等效项 [C/C++]
【发布时间】:2014-04-15 00:24:39
【问题描述】:

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

在 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 c++ enums namespaces constants


【解决方案1】:

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

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

jycr753 已经链接了this question,它确实显示了您如何在 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

结果输出是:

全局 FOOBAR 常量为:全局 Foo::FOOBAR 是:123 酒吧::FOOBAR 是:456 工作::FOOBAR 是:工作

当然,实际上,您的代码会分布在多个文件中,而且通常情况下,您只会为该文件使用一个命名空间,而 use 其他命名空间(≃ using in 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 有它的缺点,但是当然,我们都知道这么多,至于你的问题,我相信你现在已经有了答案,我继续这种咆哮是完全没有意义的。关于命名空间你需要知道的一切都可以found in the manual, BTW

【讨论】:

  • 谢谢,我想我将不得不处理这样一个事实,即我不能像在 C++ 中那样让它看起来很好,不得不求助于其他东西。但是非常感谢您的这篇文章,无论如何它帮助了很多(:
猜你喜欢
  • 2019-07-22
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 2014-01-14
  • 2012-03-16
相关资源
最近更新 更多