©
本文档使用
php.cn手册 发布
(PHP 5 >= 5.1.0)
__halt_compiler — 中断编译器的执行
中断编译器的执行。常用于在PHP脚本内嵌入数据,类似于安装文件。
可以通过常量 __COMPILER_HALT_OFFSET__
获取数据开始字节所在的位置,且该常量仅被定义于使用了__halt_compiler的文件。
没有返回值。
Example #1 A __halt_compiler() 例子
<?php
// open this file
$fp = fopen ( __FILE__ , 'r' );
// seek file pointer to data
fseek ( $fp , __COMPILER_HALT_OFFSET__ );
// and output it
var_dump ( stream_get_contents ( $fp ));
// the end of the script execution
__halt_compiler(); the installation data ( eg . tar , gz , PHP , etc .)
Note:
__halt_compiler() 仅能够在最外层使用。
[#1] cwk32 at mail dot ustc dot edu dot cn [2015-02-23 03:11:04]
if you find the value of __COMPILER_HALT_OFFSET__ is highly strange. Maybe...
there are some complier optimization tools, like eAccelator(very old). When the program is pre-complied and cached, the __COMPILER_HALT_OFFSET__ will be 0 = =
[#2] Krzysiek [2014-07-14 09:41:54]
Joey, you're wrong saying that __halt_compiler have strange behavior. This structure works exactly the same as any other build in structure like empty or isset (even similarly to functions; at least in tokenizer level).
About T_OPEN_TAG - after one open tag is present you didn't expect other one in current php code section, so tokenizer try to handle this "thing" in other way and it's perfectly normal...
[#3] joey at gimo dot co dot uk [2014-05-25 16:10:51]
I don't exactly know what PHP is doing internally but I don't understand the sanity behind how in token_get_all __halt_compiler is handled.
This is actually valid there:
__halt_compiler ();raw
Normally it pops off just any three tokens so you can have even __halt_compiler***, __halt_compiler))), etc in token _get all.
The weird thing is that is also skips T_OPEN_TAG but in the context __halt_compiler runs in this tag should not be posible. Instead it will pick up < and ? as operators and php as a T_STRING.
It ignores the token at any point so this is also valid:
__halt_compiler() ;raw
When I test this with a php file rather than the tokeniser it works the same.
I can only conclude that PHP/__halt_compiler is pretty weird.
I think this is from attempting to weakly imitate the same syntax handling as in functions (I guess you can put comments/whitespace anywhere). I find it annoying and counter productive though.
Even this is valid:
__halt_compiler// comment\n();raw
A general problem that compound matters is that tokenise wont check whether or not syntax is valid (tokens against each other). When running as PHP you must have ();.
[#4] Anonymous [2013-12-16 10:38:37]
This is not what people expect to see on manual pages, don't take this as example.
[#5] -T- [2013-10-22 17:16:21]
What zsh mentioned six years ago: "Also, it cannot be used in eval() -- it won't throw a syntax error, but it won't do anything either." is wrong. It can be used in eval() -- it will halt the eval.
[#6] ravenswd at gmail dot com [2010-06-29 06:16:19]
__halt_compiler is also useful for debugging. If you need to temporarily make a change that will introduce an error later on, use __halt_compiler to prevent syntax errors. For example:
<?php
if ( $something ):
print 'something';
endif; // endif placed here for debugging purposes
__halt_compiler();
endif; // original location of endif -- would produce syntax error if __halt_compiler was not there
?>
[#7] Ultimater at gmail dot com [2009-05-14 06:36:18]
Another possible usage, in addition to binary data and installers,
is using it to separate model, view and controller logic from one another:
<?php
class viewhelper{function render(){
eval(file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__));
}}
//database logic goes here
$row=array(
'loggedin'=>true,
'modcp'=>true,
'admincp'=>false,
'username'=>'Ultimater',
'userid'=>1234
);
//database logic goes here
//controller logic goes here
$view=new viewhelper;
$view->title="Test -> Ultimater's MVC example";
$view->base="http://".$_SERVER['HTTP_HOST'];
$view->username=$row['username'];
$view->userid=$row['userid'];
$view->authbar->loggedin=$row['loggedin'];
$view->authbar->modcp=$row['modcp'];
$view->authbar->admincp=$row['admincp'];
$view->render();
//controller logic goes here
__halt_compiler();?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>
<?php=htmlentities($this->title)?>
</title>
<style type="text/css">
a{color:#3333ff;text-decoration:none;}
a:hover{color:#0380fc;}
</style>
</head>
<body>
<?php
if($this->authbar->loggedin){
?>
<table><tr>
<td>Hello <a href="
<?php=$this->base?>
/showuser.php?id=
<?php=$this->userid?>
</a></td><td>[</td>
"><?php=htmlentities($this->username)?>
<td><a href="
<?php=$this->base?>
/logout.php">Log Out</a></td>
<th><a href="
<?php=$this->base?>
/usercp.php">UserCP</a></th>
<?php if($this->authbar->modcp){ ?>
<td>·</td><th><a href="
<?php=$this->base?>/modcp.php">ModCP</a></th>
<?php } ?>
<?php if($this->authbar->admincp){ ?>
<td>·</td><th><a href="
<?php=$this->base?>/admincp.php">AdminCP</a></th>
<?php } ?>
<td>]</td>
</tr></table>
<?php
}else{
?>
<table><tr><td>Hello Guest</td><td>[</td>
<td><a href="
<?php=$this->base?>
/login.php">Log In</a></td>
<th><a href="
<?php=$this->base?>
/register.php">Register</a></th>
<td>]</td></tr></table>
<?php } ?>
</body>
</html>
[#8] zsh [2007-10-12 04:11:58]
__halt_compiler() is a language construct and therefore cannot be used as a variable function.
Also, it cannot be used in eval() -- it won't throw a syntax error, but it won't do anything either.