此函数可在eval()中使用——它将停止eval,但不会停止调用eval()的脚本。
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
__halt_compiler — 停止编译器执行
停止编译器的执行。这对于将数据嵌入PHP脚本中非常有用,例如安装文件。
数据起始的字节位置可以通过__COMPILER_HALT_OFFSET__
常量确定,该常量仅在文件中存在__halt_compiler()时才定义。
此函数没有参数。
不返回任何值。
示例 #1 一个 __halt_compiler() 示例
<?php
// 打开此文件
$fp = fopen(__FILE__, 'r');
// 将文件指针移到数据位置
fseek($fp, __COMPILER_HALT_OFFSET__);
// 并输出它
var_dump(stream_get_contents($fp));
// 脚本执行结束
__halt_compiler(); 安装数据 (例如. tar, gz, PHP, 等等.)
注意:
__halt_compiler() 只能在最外层作用域中使用。
__halt_compiler对于调试也很有用。如果您需要临时进行更改,稍后会引入错误,请使用__halt_compiler来防止语法错误。例如
<?php
if ( $something ):
print 'something';
endif; // 为调试目的在此处放置endif
__halt_compiler();
endif; // endif 的原始位置——如果没有 __halt_compiler,则会产生语法错误
?>
如果“__halt_compiler();”出现在被“include”或“require”的文件中,则调用的文件将被视为在“__halt_compiler();”处物理中断。换句话说,“__halt_compiler();”只影响它所在的物理文件,包含它的外部文件将继续执行。
Joey,你说__halt_compiler行为异常是错误的。此结构的工作方式与任何其他内置结构(如empty或isset)完全相同(甚至与函数类似;至少在标记器级别)。
关于T_OPEN_TAG - 在当前PHP代码段中存在一个打开标签后,您不希望出现另一个打开标签,因此标记器尝试以其他方式处理此“内容”,这是完全正常的……
请注意,如果从pharstub中使用__HALT_COMPILER(),则必须大写:https://php.net/manual/en/phar.fileformat.stub.php
我不完全知道PHP内部在做什么,但我无法理解token_get_all中如何处理__halt_compiler背后的原理。
这实际上在那里是有效的
__halt_compiler/**/ /**/ /**/ /**/ /** */();raw
通常它只会弹出任意三个标记,因此您甚至可以在token _get all中使用__halt_compiler***、__halt_compiler)))等。
奇怪的是,它还会跳过T_OPEN_TAG,但在__halt_compiler运行的上下文中,此标记不应该出现。相反,它会将<和?作为运算符,并将php作为T_STRING。
它在任何时候都会忽略标记,因此这也有效
__halt_compiler()/**/ /**/ /**/ /**/ /** */;raw
当我在PHP文件中而不是标记器中测试它时,它的工作方式相同。
我只能得出结论,PHP/__halt_compiler非常奇怪。
我认为这是试图弱模仿函数中相同的语法处理(我想你可以在任何地方放置注释/空格)。但我认为这很烦人和适得其反。
甚至这也有效
__halt_compiler// comment\n();raw
一个加剧问题的一般问题是标记器不会检查语法是否有效(标记彼此)。在作为PHP运行时,您必须具有();。
如果您发现__COMPILER_HALT_OFFSET__的值非常奇怪。也许……
有一些编译器优化工具,例如eAccelator(非常旧)。当程序被预编译和缓存时,__COMPILER_HALT_OFFSET__将为0 ==