©
This document uses PHP Chinese website manual Release
(PHP 4, PHP 5)
eval — 把字符串作为PHP代码执行
$code
)
把字符串 code
作为PHP代码执行。
The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.
code
需要被执行的字符串
代码不能包含打开/关闭 PHP tags。比如,'echo "Hi!";' must be passed instead of '<? echo "Hi!"; >'. It is still possible to leave and reenter PHP mode though using the appropriate PHP tags, e.g. 'echo "In PHP mode!"; ?>In HTML mode!<? echo "Back in PHP mode!";'.
Apart from that the passed code must be valid PHP. This includes that all statements must be properly terminated using a semicolon. 'echo "Hi!"' for example will cause a parse error, whereas 'echo "Hi!";' will work.
return 语句会立即中止当前字符串的执行。
The code will be executed in the scope of the code calling eval() . Thus any variables defined or changed in the eval() call will remain visible after it terminates.
eval() 返回 NULL
,除非在执行的代码中 return 了一个值,函数返回传递给 return 的值。
如果在执行的代码中有一个解析错误, eval() 返回
FALSE
,之后的代码将正常执行。无法使用 set_error_handler() 捕获 eval() 中的解析错误。
Example #1 eval() 例子 - 简单的文本合并
<?php
$string = 'cup' ;
$name = 'coffee' ;
$str = 'This is a $string with my $name in it.' ;
echo $str . "\n" ;
eval( "\$str = \" $str \";" );
echo $str . "\n" ;
?>
以上例程会输出:
This is a $string with my $name in it. This is a cup with my coffee in it.
Note: 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。
和直接将结果输出到浏览器一样,可使用输出控制函数来捕获当前函数的输出,然后(例如)保存到一个 string 中。
Note:
如果在执行的代码中产生了一个致命的错误(fatal error),整个脚本会退出。
[#1] turboflash [2015-08-05 18:39:23]
Sharing a code which might be useful to someone. my_eval() is useful if
- You don't want to introduce new variables like what eval() would do.
- You just want to execute some calculations or some file/database retrieval and return the result.
- By returning the result in an array, you can differentiate a FALSE between a parse error or a result returned by the $code.
function my_eval($code) {
$my_code = '$my_function = function () {' . $code . '}; return array($my_function());';
return eval($my_code);
}
[#2] lord dot dracon at gmail dot com [2015-07-31 13:46:59]
Inception with eval()
<pre>
Inception Start:
<?php
eval("echo 'Inception lvl 1...\n'; eval('echo \"Inception lvl 2...\n\"; eval(\"echo \'Inception lvl 3...\n\'; eval(\'echo \\\"Limbo!\\\";\');\");');");
?>
[#3] Experienced programmer [2015-05-27 18:56:18]
I have coding experience since 1980 since I was 13 years old (have programmed ALL/Most languages from Z80/6502/8080 upwards). I have owned technology and IT businesses since 1989.
eval is NO MORE dangerous than a 'user' having access to root deleting the partition with fdisk (or any other command/statement/function).
It is all about proper design and engineering, and, control/policy. But we live in a 'freelance' world where anybody who can 'cut-and-paste' is a programmer working for the cheapest bidder (aka outsourcing).
[#4] Karel [2015-02-03 16:23:51]
For them who are facing syntax error when try execute code in eval,
<?php
';
$str = '<?php echo "test"; ?>
eval('?>'.$str.'
<?php;'); // outputs test
'.$str.'
eval('?>
<?php'); // outputs test
'.$str.'
eval('?>
<?php');// throws syntax error - unexpected $end
?>
[#5] andrea at donboscoland dot it [2014-04-27 15:03:02]
with reference to the problem of mathematic equations validation
, as an operator is not a good idea... i've removed the comma from operators and added the optional group (,(?1))? to validate functions like pow(2,3)
$operators = '[\
}
catch (SystemExit $e) { }
// end of file: index.php
// some deeply nested function or .php file
if (SOME_EXIT_CONDITION)
throw new SystemExit(); // instead of exit()
?>
[#6] vincent dot laag at gmail dot com [2010-09-24 12:51:31]
Don't use the exit() function in the auto prepend file with fastcgi (linux/bsd os).
It has the effect of leaving opened files with for result at least a nice "Too many open files ..." error.
[#7] matt at serverboy dot net [2010-03-23 12:11:57]
It should be noted that if building a site that runs on FastCGI, calling exit will generate an error in the server's log file. This can quickly fill up.
Also, using exit will diminish the performance benefit gained on FastCGI setups. Instead, consider using code like this:
<?php
if( )
echo "Invalid request";
else {
}
?>
I've also seen developers get around this issue with FastCGI by wrapping their code in a switch statement and using breaks:
index.php:
<?php
switch(true) {
case true:
require('application.php');
}
?>
application.php:
<?php
if($x > $y) {
echo "Sorry, that didn't work.";
break;
}
// ...
?>
It does carry some overhead, but compared to the alternative, it does the job well.
[#8] albert at removethis dot peschar dot net [2009-05-05 11:50:27]
jbezorg at gmail proposed the following:
<?php
if($_SERVER['SCRIPT_FILENAME'] == __FILE__ )
header('Location: /');
?>
After sending the `Location:' header PHP _will_ continue parsing, and all code below the header() call will still be executed. So instead use:
<?php
if($_SERVER['SCRIPT_FILENAME'] == __FILE__)
{
header('Location: /');
exit;
}
?>
[#9] jbezNULLorg at gmNULLail dot com [2009-02-24 12:26:57]
If you are retroactively going through included files to prevent them from being accessed, you can use the following.
<?php
if($_SERVER['SCRIPT_FILENAME'] == __FILE__ )
header('location: /'); // or exit();
// rest of code
?>
[#10] void a t informance d o t info [2008-10-26 14:11:00]
To rich dot lovely at klikzltd dot co dot uk:
Using a "@" before header() to suppress its error, and relying on the "headers already sent" error seems to me a very bad idea while building any serious website.
This is *not* a clean way to prevent a file from being called directly. At least this is not a secure method, as you rely on the presence of an exception sent by the parser at runtime.
I recommend using a more common way as defining a constant or assigning a variable with any value, and checking for its presence in the included script, like:
in index.php:
<?php
define ('INDEX', true);
?>
in your included file:
<?php
if (!defined('INDEX')) {
die('You cannot call this script directly !');
}
?>
BR.
Ninj
[#11] emils at tvnet dot lv [2003-08-23 08:14:28]
Note, that using exit() will explicitly cause Roxen webserver to die, if PHP is used as Roxen SAPI module. There is no known workaround for that, except not to use exit(). CGI versions of PHP are not affected.
[#12] mbostrom at paragee dot com [2003-02-26 12:45:49]
In PHP 4.3.1 (and possibly 4.3.0), running scripts from the command line works a lot better. This is probably because 4.3.x has a whole new CLI mode.
Specifically, exit status is now returned (to the shell) as you would expect. This is a godsend for writing embedded email processing scripts, as much email infrastructure (fetchmail, qmail, mutt, etc.) is dependant upon correctly returned status codes, and the inability to return a status code (as in PHP 4.2.x) is an insurmountable obstacle.
$_SERVER["argv"] is also always available in 4.3.x, I think, whereas in 4.2.x php.ini could prevent it from being available.
(On the downside, I had to ./configure --without-mysql in order to get 4.3.1 to compile on RedHat 8.0. Otherwise there was what looked like a fatal compile warning (that I might also have been able to ignore somehow).
The "fatal warning" FYI:
ext/mysql/libmysql/my_tempnam.o: In function `my_tempnam':
ext/mysql/libmysql/my_tempnam.c:103: the use of `tempnam' is dangerous, better use `mkstemp'
Changing the code from tempnam to mkstemp would probably not be overly complicated, but it is non-trivial.)
[#13] shaun at NOshatSPAM dot net [2002-08-09 04:13:39]
return may be preferable to exit in certain situations, especially when dealing with the PHP binary and the shell.
I have a script which is the recipient of a mail alias, i.e. mail sent to that alias is piped to the script instead of being delivered to a mailbox. Using exit in this script resulted in the sender of the email getting a delivery failure notice. This was not the desired behavior, I wanted to silently discard messages which did not satisfy the script's requirements.
After several hours of trying to figure out what integer value I should pass to exit() to satisfy sendmail, I tried using return instead of exit. Worked like a charm. Sendmail didn't like exit but it was perfectly happy with return. So, if you're running into trouble with exit and other system binaries, try using return instead.
[#14] devinemke at devinemke dot com [2002-01-11 00:38:15]
If you are using templates with numerous includes then exit() will end you script and your template will not complete (no </table>, </body>, </html> etc...). Rather than having complex nested conditional logic within your content, just create a "footer.php" file that closes all of your HTML and if you want to exit out of a script just include() the footer before you exit().
for example:
include ('header.php');
blah blah blah
if (!$mysql_connect) {
echo "unable to connect";
include ('footer.php');
exit;
}
blah blah blah
include ('footer.php');