文字

__halt_compiler

(PHP 5 >= 5.1.0)

__halt_compiler 中断编译器的执行

说明

void __halt_compiler ( void )

中断编译器的执行。常用于在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?>
"><?php=htmlentities($this->username)?>
</a></td><td>[</td>
<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>&middot;</td><th><a href=" <?php=$this->base?>/modcp.php">ModCP</a></th>
<?php ?>

<?php if($this->authbar->admincp){ ?>
<td>&middot;</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.

上一篇: 下一篇: