为什么null可以用反斜杠写?

时间:2019-04-16 11:49:23

标签: php null namespaces constants

在所有PHP手册中,它都说nulltruefalse是内部值。但是,没有地方说明为什么可以使用反斜杠来写它们:\null\false\true

PHP中的nullfalsetrue到底是什么?

一个常量,或者他们是解释器的骇客?

2 个答案:

答案 0 :(得分:5)

nullfalsetrue在PHP中定义为常量。反斜杠表示global namespace,因此您可以为这些常量指定完整的命名空间,例如:\null。这是不必要的,因为所有常量都是全局常量(使用const定义的常量除外)。

  

就像超全局变量一样,常量的范围是全局的。您可以在脚本中的任何位置访问常量,而无需考虑范围。有关范围的更多信息,请阅读有关变量范围的手册部分。 -PHP Manual on Constants

函数和常量不需要完全限定的名称。这与classes which must be specified with their namespace例如\Exception

  

对于函数和常量,如果没有命名空间的函数或常量,PHP将退回到全局函数或常量。 -PHP Manual on namespace fallback

编辑

nullfalsetrue是PHP中非常特殊的常量。它们是唯一仍显式“不区分大小写” 的文件。之所以将其用引号引起来,是因为实际的常量名称被定义为NULLFALSETRUE,但实际上不是。小写:

define('TRUE', 'foo'); // works
define('True', 'bar'); // works too, even in combination with the first one
define('true', 'abc'); // Notice: Constant true already defined

var_dump(constant('TRUE')); // string 'foo'
var_dump(constant('True')); // string 'bar'
var_dump(constant('true')); // boolean true

如果删除define() -s,则即使使用constant('True'),所有常量也会指向布尔值。 -https://ideone.com/CZSwiX

PHP手册状态:

  

要指定布尔文字,请使用常量TRUE或FALSE。两者都不区分大小写。

那么您可能会问自己,这些常数的值是多少?如果执行var_dump(TRUE);,则结果将为bool(true);如果执行echo true;,则结果将输出1。它们在PHP源代码中的定义是什么? Here is the answer

REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT);
REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT);
REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT);

更有趣的是,它们实际上被视为special constants,并且不能由用户重新定义(其他预定义的常数可以使用const在其自己的命名空间中重新定义)。因此,我认为,出于所有意图和目的,您可以将这3个不仅视为常量,而且还应将其视为类似于保留关键字的特殊值。目前,它们仍然在PHP中实现为不区分大小写的hack,但作为@NikiC在commit中的注释指出:“将来,我们可能会将它们从常量转换为保留关键字。”

有趣的事实:直到PHP 7 truefalsenull都不是保留关键字,因此您可以try something like this

class TRUE {
    const int = 'This is the truest of the integers';
}
var_dump(TRUE::int);

tl; dr:
访问\null\false\true是有效的,因为它们在内部定义为特殊常量,并且PHP中的所有常量都位于全局命名空间中。

答案 1 :(得分:4)

nulltruefalse都是文档定义的常量:

  

只有一个类型为null的值,即不区分大小写的常量NULL。

  

要指定布尔文字,请使用常量TRUE或FALSE。两者都不区分大小写。

\放在它们前面时,它会强制PHP在全局名称空间中查找。

同样,您可以通过定义自己的常量进行测试:

define('TEST', 'true');

var_dump(\TEST); // string(4) "true"

命名空间常量的另一个示例:

namespace Test {
  const A = 'A';
}

namespace { // Global namespace
  const A = 'B';

  echo A . PHP_EOL; // B
  echo Test\A . PHP_EOL; // A
}

如果在分类参数设置为true的情况下查看get_defined_constants,则会看到TRUEFALSENULL中定义的{ Core