`while (true)`和`while (\true)`之间有什么区别?

25

while (true)while (\true) 有什么区别? 更重要的是,为什么在 PHP 中命名空间会影响 boolean 类型?


8
这篇文章已经看起来好了一些。但顶部有一个效率不高的FETCH_CONSTANT指令。这需要针对igorw\true进行名称空间查找。我们可以通过将while(true)替换为while(\true)来进行优化。这样就可以消除FETCH_CONSTANT调用,并将布尔值true内联处理。 - Funk Forty Niner
2
TRUE/FALSE 会像其他常量一样运作。请参考 http://php.net/manual/en/reserved.constants.php。 - Michael Berkowski
4
自 PHP 5.3.0 版本起,所有函数/类/变量/常量等都有命名空间,true/false/null/etc 也是常量,就像你可能自己定义的任何常量一样。它们中的大多数在全局命名空间中,但是如果 PHP 在当前命名空间中找不到它们,则会首先检查当前命名空间,然后检查全局命名空间,因此使用 \ 前缀可以避免当前命名空间检查的开销。 - Mark Baker
@Fred-ii- NikiC 刚刚确认由于实现中的一个错误,导致了 FETCH_CONSTANT 被调用。 - Baba
1
@Baba 很高兴知道错误已经被找到。感谢您的更新。 - Funk Forty Niner
显示剩余2条评论
1个回答

56
在PHP中,truefalsenull是常量,受到命名空间保护,不能被覆盖。因此,以下代码是无效的:
namespace Foo;
const true = false; // Cannot redeclare constant 'true'

使用 "define()" 仍然可以覆盖这样的常量:

namespace Foo;
define('Foo\true', false);
var_dump(true); // bool(false)

然而,这不是被支持的功能(可能被称为错误),PHP可以自由地假设true不能被覆盖。例如,在constexpr上下文中使用true将不受上述定义的影响:

// Note: This uses eval() to make sure the define() runs before the constexpr
//       constant resolution happens

namespace Foo;
define('Foo\true', false);
var_dump(eval('namespace Foo;
static $t = true;
return $t;')); // bool(true)

在constexpr情况下发生替换的原因是实现中的一个bug。对于constexpr,替换发生在名称解析之前,而对于普通代码,则发生在名称解析之后。

正确的实现应该始终在名称解析之后进行替换,但在替换过程中特别考虑true、false和null。我计划在PHP 7中修复这个问题。


1
@tftd 不确定你是在讽刺。你知道 PHP 7 是 PHP 的下一个版本吗?我们跳过了 6。 - mpen
3
我只是开玩笑而已,不过我确实不知道 PHP 会跳过6直接升级到7。那么我就会关注 GitHub 上的 alpha 版本、beta 版本和早期快照了! :) - tftd
我敢打赌已经有渴望出版 PHP 7 书籍的出版商了,所以当那个版本没有实现所有承诺时,我们可以直接跳到 8! - Theodore R. Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接