什么是PHP中的__halt_compiler?

时间:2011-03-11 08:14:39

标签: php

来自manual

void __halt_compiler ( void )
  

此函数暂停编译器的执行。这对于在PHP脚本中嵌入数据非常有用,例如安装文件。

     

注意:__halt_compiler()只能在最外层范围内使用。

任何人都可以提供此功能有用的实际案例吗?

3 个答案:

答案 0 :(得分:55)

假设你有一个带有一些PHP代码和大量二进制混乱的脚本。

<?php doStuff(); __halt_compliler(); [BIG_BINARY_MESS]

那么你希望编译器不要尝试解析二进制文件,因为如果二进制文件中某处有<?它会破坏。

关键是能够发送带有二进制数据和PHP代码的一个文件。

有关示例,请参阅this blog post


因此,您不仅要停止脚本的execution(例如exit()会),还要停止parsing,以便您可以在结尾处使用“无效语法”文件和php仍然可以执行第一部分。


另一个例子:

这将被解析为有效的php并执行得很好:

<?php $a = 1; echo $a; __halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();

访问数据:

<?php
$file = fopen(__FILE__, 'rb');
// Go to the end of the __halt_compiler();
fseek($file, __COMPILER_HALT_OFFSET__);
echo stream_get_contents($file);
__halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();

这将输出§RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();

答案 1 :(得分:6)

以前,ClassGenerator in the PhpSpec单元测试库提供了使用__halt_compiler()的一个很好的示例,PHP class contains a code template for a PHP class

他们最近更新以从单独的文件中读取模板,但最初getTemplate()方法将尝试读取__halt_compiler()调用之后的文件中提供的PHP代码模板。这样可以避免解析<?php令牌。

/**
 * The Class Generator is responsible for generating the classes from a resource
 * in the appropriate folder using the template provided
 */
class ClassGenerator
{
    //...

    /**
     * @return string
     */
    protected function getTemplate()
    {
        return file_get_contents(__FILE__, null, null, __COMPILER_HALT_OFFSET__);
    }
}
__halt_compiler();<?php%namespace_block%

class %name%
{
}

答案 2 :(得分:3)

这是另一种可能的用途。我有一个很长的PHP函数文件。其中许多目前无效,但可能很快就会被要求。我想禁用它们,但不完全删除它们。我希望代码对所有开发人员保持可见,以便他们可以在需要时恢复代码。任何通过grep搜索的人都会找到代码。

所以我将代码移到文件的末尾,并希望“将其注释掉”。但是函数本身也有注释。所以我需要在原始代码中的每个块注释结束后开始一个新的块注释。 __halt_compiler();在不改变任何其他行的情况下完成工作。

(如果我删除代码并将其提交给版本控制系统,这确实允许我恢复代码,但除非他们看起来新的,否则它将不会被其他开发人员看到。)