【问题标题】:Single-letter prefix for PHP class constants?PHP类常量的单字母前缀?
【发布时间】:2010-03-19 17:25:30
【问题描述】:

我注意到许多(全部?)PHP 常量都有一个单字母前缀,例如E_NOTICET_STRING 等。在定义一组相互配合工作的类常量时,您更喜欢遵循类似的做法,还是更喜欢更冗长?

class Foo {
    // let's say 'I' means "input" or some other relevant word
    const I_STRING = 'string';
    const I_INTEGER = 'integer';
    const I_FLOAT = 'float';
}

class Bar {
    const INPUT_STRING = 'string';
    const INPUT_INTEGER = 'integer';
    const INPUT_FLOAT = 'float';
}

【问题讨论】:

  • 这确实是一个留给 wiki 的主观问题。这里没有正确或错误的答案。

标签: php constants


【解决方案1】:

在 5.3 之前,PHP 仅限于单个全局命名空间。这意味着任何使用 define 声明或内置于语言中的常量都需要一个前缀来对自身进行分区——如果你愿意的话,命名空间很便宜。

关于常量本身:虽然E_NOTICEERROR_NOTICE 更容易键入,但前者的主要缺点是不能自我记录。在全局上下文中,您不仅需要按前缀划分常量,这些前缀还应尽可能具有描述性。

类常量是一个稍微不同的野兽,因为你总是通过类名来引用它们——分区是内置的。所以你最终会得到Account::STATUS_CONFIRMEDAccount::STATUS_BANNED。但是如果我计划拥有几十个状态,我会将它们放在他们自己的类中,例如AccountStatus::CONFIRMEDAccountStatus::BANNED

无论您为常量决定何种命名约定,主要考虑因素是分区和自记录名称(冗长)。

【讨论】:

    【解决方案2】:

    对于常量之类的东西,我更喜欢冗长。我发现它使代码在以后更容易理解(或者对于那些没有编写它的人),并且由于我使用 IDE,我通常不必担心在编码时输入整个长名称。

    【讨论】:

    • 我实际上并不担心打字,而是担心吃掉半行代码。在我的特殊情况下,我有一个 18 或 19 个字符的类名,加上 '::',加上前缀、下划线和常量名,我们说的是近 40 个字符。我个人不遵守严格的 80 个字符行限制,但有些人会这样做。感觉……效率低下。
    • (但同时,我完全同意你的逻辑)
    • 我 100% 听到你的声音。事情很快就会变得笨拙。不幸的是,我没有灵丹妙药。
    【解决方案3】:

    在类中,最好不要使用前缀,除非它们在上下文中非常有意义。您在常量中看到的字母前缀是因为 PHP 在引入命名空间时没有命名空间;但是类是某种形式的命名空间,所以这不是必需的。

    但是,如果您仍然要使用前缀,我建议您使用最有意义的前缀——也就是说,使用完整的单词而不是单个字母。我不会猜到I 的意思是INPUT

    【讨论】:

      【解决方案4】:

      大多数 PHP 常量都有前缀的原因是给它们命名空间,这样 .例如,在E_USER_ERROR 中,E_ 做了两件事:

      1. 它告诉你该常量与错误处理系统有关
      2. 如果您想在应用程序中拥有一个名为 USER_ERROR 的常量,您可以这样做。

      在 PHP5 中,我们可以使用类常量,因此不再需要命名空间。参见例如DATE_ constantsDATE_ATOM 的等价物是DateTime::ATOM,其中DateTime 是处理日期的PHP 类。 DATE_ATOM 仍然存在,可能是出于遗留原因,但如果今天创建了这个常量,它就会被简单地称为 DateTime::ATOM

      在您的情况下,定义一个具有这些常量的输入类可能是有意义的:

      class input {
          public const STRING='string';
          public const INTEGER = 'integer';
          public const FLOAT = 'float';
      }
      

      【讨论】:

        【解决方案5】:

        我更喜欢更冗长

        class Bar {
            const INPUT_STRING = 'string';
            const INPUT_INTEGER = 'integer';
            const INPUT_FLOAT = 'float';
        }
        

        这使下一个必须处理代码的人更容易阅读代码。您可以考虑将自己的框架前缀添加到常量(例如:XYZ_INPUT_STRING),这将减少与您可能使用的其他组件发生冲突的变化。更冗长的一个缺点是变量名往往会变得更长,但一个好的 IDE 支持代码完成,因此您不必输入整个变量名。

        【讨论】:

        • 除非您解释原因并且不复制/粘贴问题,否则不会为您 +1。
        【解决方案6】:

        前缀用于命名符号。例如。由于常量是在全局范围内声明的,因此您可以使用前缀来指定它的上下文,并避免与该符号在不同上下文中的其他用途发生冲突。

        由于类常量已经存在于上下文(类)中,因此实际上不需要进一步添加前缀。而不是你的例子,这可能更有意义:

        class Input {
          const STRING = 'string';
          const INTEGER = 'integer';
          const FLOAT = 'float';
        }
        

        也就是说,我发现常量(类或全局)通常不是我在 PHP 中经常使用的东西。您通常可以用更具体的方法名替换常量,这通常会使代码更易于维护。例如,而不是这样的:

        $foo->addParameter("foo", Input::STRING);
        

        你可以这样做:

        $foo->addStringParameter("foo");
        

        更容易阅读并且更容易写。

        【讨论】:

          【解决方案7】:

          与 C 和其他朋友不同,在动态语言中,我们很少(如果有的话)需要预先声明的常量。因为描述性字符串值也可以正常工作。使用没有真正的好处

          if($account->status == AccountStatus::CONFIRMED)
          

          相比

          if($account->is('confirmed'))
          

          后者更具可读性并且需要更少的代码。

          在你开始写一个愤慨的评论之前,看看 jQuery 是如何做到的:http://api.jquery.com/animate/。 'hide'、'toggle'、'fast' 等实际上是常量,它们根本没有这样声明。

          【讨论】:

          • 当类的内部行为发生变化并且需要修改常量时会发生什么?使用声明的常量使代码维护更易于管理。
          • 我更喜欢$account->isConfirmed()
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-21
          相关资源
          最近更新 更多