NAMESPACE_SEPARATOR常数

时间:2010-05-18 07:55:37

标签: php coding-style namespaces

在PHP中使用命名空间非常棒。将'\'作为命名空间分隔符有点......尴尬(但如果有人认为这很酷且性感,我会在这篇文章中添加标签“rant”。)。

所以,问题就在这里:

您是否在代码中使用NAMESPACE_SEPARATOR常量?如下面的代码所示:

<?php

if (!\defined('NAMESPACE_SEPARATOR') {

    \define('NAMESPACE_SEPARATOR', '\\');

} // if

优点:

  • 与DIRECTORY_SEPARATOR一致(所有我们正在使用;)
  • 没有逃脱的混乱(想想'\ Foo \ Bar''\\'。Foo'。'\\'。'Bar'
  • 更具可读性(恕我直言)
  • 这使我们有机会编写好的,名称空间感知的自动加载器
  • 如果发生可怕的事情,
  • 可以抵制另一种变化(就像使用来自PHP 6 alpha的ol'good'::')
  • 可以隐藏'\'作为编程语言中的名称空间操作符来自陌生人;)

缺点:

  • DIRECTORY_SEPARATOR的原因是该值与平台有关,而命名空间分隔符则不是。” (如http://bugs.php.net/bug.php?id=43046
  • 中所述
  • 19个字符而不是1个( \ )或4个('\\'
  • 有些地方你不能使用它(完全限定类名作为默认类变量),即:

    <?php
    
    class A {
    
        protected $sDefaultReporterClass = '\My\Namespace\DefaultReporter';
    
    }
    

那么,你在想什么?

3 个答案:

答案 0 :(得分:6)

我不确定我的观点是什么...... PHP常量与C预处理器宏不同。您无法创建宏并用它替换运算符 - 它只是不起作用:

<?php
define('ADD', '+');
echo (3 ADD 5); // Parse error: syntax error, unexpected T_STRING
?>

即使它奏效了,目的是什么?隐藏语言的语法使其看起来像您熟悉的另一种语言是相当浪费时间,更不用说它使其他编码人员更难以处理项目。如果您认为语言X看起来更酷,那么,只需编写代码X而不是PHP:)

更新

在使用单引号的地方使用命名空间分隔符(例如自动加载程序和回调)几乎没有什么困难,因为它只需要转义需要转义的地方就在引号或另一个反斜杠之前,因此它可以按原样编写:

$callback = 'Foo\Bar';

所有其他选项在我看来都是不必要的复杂性:

$callback = "Foo\\Bar";
$callback = 'Foo' . NAMESPACE_SEPARATOR . 'Bar';
$callback = "Foo{$namespace_separator}Bar";

答案 1 :(得分:6)

是您问题的答案。我使用自定义的NAMESPACE_SEPARATOR,因为

str_replace(NAMESPACE_SEPARATOR, DIRECTORY_SEPARATOR, $classFileName);

比我更清楚

str_replace('\\', DIRECTORY_SEPARATOR, $classFileName);

它可能只在我的自动加载机中使用,但我想快速理解代码,如果我几年后就读它了。

答案 2 :(得分:1)

现在或多或少通过使用新的(PHP&gt; 5.5)方法通过使用class name resolution(在PHP RFC中称为class name scalars)来解决类名来解决此问题。

虽然使用填充了类名的字符串对于所有类型的魔法仍然有用,特别是自动加载,使用完全限定的类名作为硬编码字符串容易出错且难以检测到IDE。

这是如何回答原始问题的:有时命名空间分隔符常量对于代码的非常特定部分很有用,尽管我会遇到实际使用它的地方较少的地方。

在您的示例中,您宁愿使用:

<?php

namespace My\Namespace;

class A {
    protected $sDefaultReporterClass = DefaultReporter::class;
// or
    protected $sAnotherReporterClass = \Other\Namespace\Reporter::class;
}

当此问题的范围如此之小时,它将仅用于代码的特定部分,这可能不会使PHP内置常量合法化。如果是这样,其他运算符(如作用域运算符)也应作为常量包含在内。 &#34; ::&#34;的PAAMAYIM_NEKUDOTAYIM常量? (抱歉小常数命名phun)

一个未实现的PHP功能,可以在这种方法之后派上用场,它将是神奇的Class :: namespace常量。