|
|
 |
die | exit |  | | Last updated: Thu, 19 May 2005 |
eval (PHP 3, PHP 4, PHP 5 ) eval -- Evaluate a string as PHP code Descriptionmixed eval ( string code_str )
eval() evaluates the string given in
code_str as PHP code. Among other things,
this can be useful for storing code in a database text field for
later execution.
There are some factors to keep in mind when using
eval(). Remember that the string passed must
be valid PHP code, including things like terminating statements
with a semicolon so the parser doesn't die on the line after the
eval(), and properly escaping things in
code_str.
Also remember that variables given values under
eval() will retain these values in the main
script afterwards.
A return statement will terminate the evaluation of
the string immediately. As of PHP 4, eval() returns
NULL unless return is called in the evaluated
code, in which case the value passed to return is
returned. In case of a parse error in the evaluated code,
eval() returns FALSE.
In case of a fatal error in the evaluated code, the whole script exits.
In PHP 3, eval() does not return a value.
Example 1.
eval() example - simple text merge
|
<?php
$string = 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo $str. "\n";
eval("\$str = \"$str\";");
echo $str. "\n";
?>
|
The above example will output: This is a $string with my $name in it.
This is a cup with my coffee in it. |
|
Tip: As with anything that outputs
its result directly to the browser, you can use the output-control functions to capture
the output of this function, and save it in a
string (for example).
See also call_user_func().
User Contributed Notes
eval
tristan at moviesoundclips dot net
17-May-2005 05:07
Correction for that last entry:
Creating a dynamic variable name in PHP does not require the eval() function (unlike javascript).
eg.
for($x = 0; $x < 3; ++$x){
echo("form.txtNum".$x.".value = '".(${"txtName".$x})."';");
}
tristan at moviesoundclips dot net
17-May-2005 11:17
The eval() can be used inline to create dynamic variable names.
echo("form.txtNum".$x.".value = '".eval("$txtNum"."$x;")."';");
alekcander at gmail dot com
06-May-2005 03:57
Attention: if you are trying to eval contents of html template it's realy recommended to use addslashes before eval or you will have parsing errors
jtraenkner
10-Apr-2005 11:11
Using eval inside loops is very slow, so try avoiding code like
<?php
for($i=0;$i<10;$i++) {
eval('do_something()');
}
?>
If you absolutely have to, include the entire loop in eval:
<?php
eval('for($i=0;$i<10;$i++) {'.
'do_something();'.
'}');
?>
tom
29-Mar-2005 01:59
Eval can't be used as a callback function so if you want to use the eval function name dynamically use this simple work around:
<?
if ($function_name == "eval")
{
eval($stuff);
}
else
{
$function_name($stuff);
}
?>
Ben Grabkowitz
26-Mar-2005 08:57
The eval function becomes incredibly useful when dealing with static class members and variables.
For instance:
Lets say you have 3 classes; Foo, BarA and BarB, where BarA and BarB are children of Foo.
Now lets also say that both BarA and BarB contain a static member function called getDataSource().
To call getDataSource() you would have to use the syntax:
BarA::getDataSource();
BarB::getDataSource();
But lets say you need to access getDataSource() from inside class Foo during an instance of either BarA or BarB.
You can use eval to do something like this:
eval('$dataSource=' . get_class($this) . '::getDataSource();');
relic at daimi dot au dot dk
15-Mar-2005 03:19
A small heads up regarding numbers and forms:
If you do
<?php
eval('\$foo = 023;');
?>
The value of $foo will be 19, because 023 is evaluated as an octal number.
Why is this interesting?
It created an odd problem for me because I had a form field taking a number from the user. This number was part of an eval. The field had a default 0 in it and the user would just put 23 behind that without deleting the 0 first, expecting it (understandably) to have the value 23.
Note also that if you do
<?php
$bar = (integer) "023";
$foobar = (integer) 023;
?>
The value of $bar will be 23, as expected, while the value of $foobar will be 19. It is quite consistent but imagine my confusion...
In light of this the solution in my case was to do
<?php
eval('\$foo = (integer) "023";');
?>
francois at bonzon dot com
27-Feb-2005 09:20
An obvious security reminder, which I think wasn't yet mentioned here. Special care is required when variables entered by the user are passed to the eval() function. You should validate those user inputs, and really make sure they have the format you expect.
E.g., if you evaluate math expressions with something like
<?php
eval("\$result = $equation;");
?>
without any check on the $equation variable, a bad user could enter in the $equation field
""; echo file_get_contents('/etc/passwd')
- or whatever PHP code he wants! - which would evaluate to
<?php
$result = ""; echo file_get_contents('/etc/passwd');
?>
and seriously compromising your security!
Geoff Eby
24-Feb-2005 09:51
I couldn't find an example of what I wanted to do, which was dynamically create and handle enumerated variables from a form, so here it is in simplified form:
<?php
echo("<table>");
$counter=0;
for ($a=0;$a<count($timeslots);$a++) {
echo("<tr>");
for ($i=0;$i<3;$i++) {
$counter++;
$fieldwithcounter="fieldname$counter";
$var1=$_POST[$fieldwithcounter];
$nextfield="second$counter";
$var2=$_POST[$nextfield];
$thirdfield="lastfield$counter";
$var3=$_POST[$thirdfield];
eval("\$grouprow$a.=\"$var1^^$var2^^$var3^^$var4\";");
echo("<td>
First field
<input type='text' name='fieldname$counter' value='$var1'><br>
Second field
<input type='text' name='second$counter' value='$var2'><br>
Last field
<input type='text' name='lastfield$counter' value='$var3'>
</td>");
}
echo("</tr>");
}
echo("</table>");
?>
james.taylor at stealthnet dot net
10-Feb-2005 03:46
Please note, eval does not return all fatal errors - there seem to be two types of fatal error - fatal error caused by script (parse, etc) and fatal error caused by death of application (memory run out, time out (?)).
Using a set-error handler does not catch these errors, they are a true death. You can not use eval to detect the death of a risky application if that involves one of these fatal errors.
See thread starting at http://news.php.net/php.general/208333 for original discussion
avenger at buynet dot com dot br
08-Feb-2005 10:52
This is a small code that uses 'eval' with a foreach (maybe 'for' loop), to fill variables. This is very useful in some hard situations:
<html><title>for loop</title><body><p align=center>
<?php
$thing = array("a","b","c");
$a = "bah" ; $b = "bleh2"; $c = "bluh3";
print("Vars b4: $a, $b, $c. ");
foreach ( $thing as $thingy ) {
print("$thingy, ");
eval("\$$thingy = \"$thingy\";");
};
print("vars aft: $a, $b, $c.");
?>
</p></body></html>
critmas at hotmail dot com
08-Feb-2005 02:46
I am using the eval(String) function as an alternate to processing instructions for XML code.
i.e.
<tag>something that I $need</tag>
when I read the value of the node (using DOM)
I ask php to evaluate the line for me to replace the value of $need.
Might be a hack, comments welcome
mat.wilmots (at) wanadoo (dot) fr
21-Jan-2005 08:16
Just a little note : eval is not a function.
Something like this
<?php
register_tick_function('eval', array('break;'));
declare(ticks=1)
{
while(true)
{
echo "Not broken yet\n";
}
}
?>
doesn't work, it says
Unable to call eval() - function does not exist
11-Jan-2005 06:11
Possible Correction for the last comment of jasperbg:
eval('?>' . $the_page . '<?php ');
Note the space behind <?php . My php5 always produced errors without the space.
jasperbg at gmail dot com
04-Jan-2005 12:09
There's a much easier way to dynamically load PHP pages:
eval('?>' . $the_page . '<?php');
where $the_page is a standard PHP page with <?php ... ?> tags around the portions to be parsed.
arnico at c4 dot lv
21-Dec-2004 05:28
Dynamically loading php pages!
In michael example ( 02-Sep-2004 05:16) is one big problem. Try to load php page with this content :
-----------------------
<?php
$a = 1;
if($a == 1){
?>
<br />ir?<br />
<?php
}
?>
------------------------
Ups? :) maybe easier way is to do something like that ? please comments :
<?php
function eval_html($string) {
$string = preg_replace("/\?>(.*?)(<\?php|<\?)/si", "echo \"\\1\";",$string);
$string = str_replace("<?php", "", $string);
$string = str_replace("?>", "", $string);
return eval($string);
}
$filename = "page.php";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo eval_html($contents);
?>
The html source will be replaced with echo. and problem is gone :) or there are other problems ? please comments.
P.S. sorry about my bad English
Amedeo
09-Dec-2004 02:00
It's more easy to write the code to be evaluated if you put it between single quotes:
<?php
$var = "aaa";
$i = 4;
$code = '$ARGS[$i]["GID"] = $var;';
eval($code);
echo ("<pre>");
print_r($ARGS);
echo ("</pre>");
?>
Which will output
Array
(
[4] => Array
(
[GID] => aaa
)
)
mahaixing at hotmail dot com
08-Oct-2004 10:49
When using Dynamic Proxy design pattern we must create a class automaticly. Here is a sample code.
$clazz = "class SomeClass { var \$value = 'somevalue'; function show() { echo get_class(\$this);}}";
eval($clazz);
$instance = new SomeClass;
// Here output 'somevalue';
echo $instance->value;
echo "<br>";
//Here output 'someclass'
$instance->show();
michael at smartgrp dot net
01-Sep-2004 09:16
After several hours of reviewing examples I believe I've come up with a decent method of dynamically loading php pages. I hope this helps, and if anyone else has any better ideas, please post them.
<?php
$eval_str = preg_match_all("/(<\?php|<\?)(.*?)\?>/si", $eval_str,
$raw_php_matches);
$php_idx = 0;
while (isset($raw_php_matches[0][$php_idx]))
{
$raw_php_str = $raw_php_matches[0][$php_idx];
$raw_php_str = str_replace("<?php", "", $raw_php_str);
$raw_php_str = str_replace("?>", "", $raw_php_str);
ob_start();
eval("$raw_php_str;");
$exec_php_str = ob_get_contents();
ob_end_clean();
$eval_str = preg_replace("/(<\?php|<\?)(.*?)\?>/si",
$exec_php_str, $eval_str, 1);
$php_idx++;
}
return $eval_str;
?>
Leigh Purdie
17-Aug-2004 03:10
This is an absolutely horrible hack, but if you're caught in a situation where you do NOT control class names, but really need to include files with potentially conflicting classes, then the following MIGHT help get you started.
Ideally, you would be able to 'uninclude' an included file, but since you cannot...
Assumptions:
* File names and class names are the same (minus '.php')
Setup:
Assume two directories, called 'One' and 'Two', both containing a file 'Goo.php', both of which implement the class "Goo".
Another file
One/
Goo.php:
<?php
Class Goo {
function blah() {
print "This is One/Goo.php\n";
}
}
?>
Two/
Goo.php:
<?php
Class Goo {
function blah() {
print "This is Two/Goo.php\n";
}
}
?>
./
test.php:
The following code (test.php) uses the 'SafeInclude' class (below):
#!/usr/bin/php -q
<?php
include_once("SafeInclude.inc");
$si=new SafeInclude();
$classname=$si->IncludeFile("One/Goo.php");
$goo=new $classname;
$goo->blah();
$classname=$si->IncludeFile("Two/Goo.php");
$goo2=new $classname;
$goo2->blah();
?>
./
SafeInclude.inc:
And here's the SafeInclude.inc file:
<?php
Class SafeInclude
{
var $count=0;
function IncludeFile($file)
{
$this->count++;
$ques="?";
if(!$file) { return(0); }
$classname=basename($file,".php");
if(class_exists($classname)) {
$newclassname=$classname . $this->count;
$contents=file($file);
$string="${ques}>";
foreach($contents as $line) {
$line=eregi_replace("^[ \t]+Class[ \t]+" . $classname," Class $newclassname",$line);
$string .= $line;
}
$string .= "<${ques}php ";
eval($string);
return($classname . $this->count);
} else {
include_once($file);
return($classname);
}
}
}
?>
Output:
$ ./test.php
This is One/Goo.php
This is Two/Goo.php
As I said, this is a horrible hack - use in emergencies only, and under controlled conditions. Anyone have any other options?
evildictaitor at hotmail dot com
15-Aug-2004 03:00
Be careful when using eval() on heavy usage sites in PHP 4.0+ as it takes vastly longer to activate due to the limitations of the Zend engine.
The Zend engine changes the PHP to a binary structure at the START of the file, and then parses it. Every time an eval is called, however, it has to reactivate the parsing procedure and convert the eval()'d code into usable binary format again.
Basically, if you eval() code, it takes as long as calling a new php page with the same code inside.
12-Jul-2004 11:37
Kepp the following Quote in mind:
If eval() is the answer, you're almost certainly asking the
wrong question. -- Rasmus Lerdorf, BDFL of PHP
info [at] derosetechnologies [dot] com
12-Jun-2004 07:15
"Bart Koelman" 's example above (OutputPhpDocument), though thouroughly functional , would benefit by using the "extract()" function in lieu of his variable exporting solution. I.e.:
<?
reset ($GLOBALS);
while (list ($key, $val) = each ($GLOBALS))
{
eval("\$" . "\$key = \"$val\";");
}
?>
Can be replaced with a single line:
<?extract($GLOBALS, EXTR_SKIP | EXTR_REFS);?>
Addtionally, this latter alternative will load the global variables as references instead of 'copies'. (Meaning that if a value is altered inside the function , that modification will also be effected outside of the OutputPhpDocument() function.
Thorsten Hamann
04-Jun-2004 07:53
To ulderico - writing self-modifying code is something you do not want to do for sufficiently complex tasks. Debugging it is a royal pain, in the more complex cases it's usually impossible. I suggest to keep away from using those techniques. A skilled programmer can always get the functionality he wants without refraining to questionable stuff like this. It was bad when we did it with assembly in the early 80's, and it's still evil today. Only today the tools allow for other ways of solving problems.
ulderico at maber dot com dot br
03-Jun-2004 06:36
For some perverted reason that I haven't manage to figure out, CONTINUE and BREAK do not break a loop OUTSIDE the eval code... Thus:
eval("
for(...){
continue;
}");
works, BUT:
for(...){
eval("continue;");
}
DO NOT WORK. Pay attention to this when you're trying to develope a program that would rewrite it's own source code using eval as a realtime compiler.
yboily at seccuris dot com
27-Feb-2004 06:46
When working with classes I was attempting to make a factory class for objects. My objective was to create a class which would create objects based on values the factory was created with.
I attempted to create the objects by calling $newObject = new $$class;
In the long run this was used to generate security settings.
<?php
class clsObject
{
var $value;
function getValue() { return $this->value; }
}
class clsSuperObject extends clsObject{
....
}
class clsFactory
{
var $baseValue;
function clsFactory($val) {$this->baseValue = $val; }
function createObject($object) {
$newObj = eval(sprintf(" return new %s();", $objType));
$newObj->value = $this->baseValue;
return $newObj;
}
}
$myFactory = new clsFactory(10);
$myObject = $myFactory->createObject("SuperObject");
$myObject2 = $myFactory->createObject("Object");
and so on ;)
I found this extremely useful.
?>
Mark Aufflick (mark at pumptheory dot com)
17-Nov-2003 11:49
Based on the excellent example by olivier at revenu dot nom dot fr, I have extended it to allow the <?= ... ?> tagged style of embedded php code:
<?php
function eval_buffer($string) {
ob_start();
eval("$string[2];");
$return = ob_get_contents();
ob_end_clean();
return $return;
}
function eval_print_buffer($string) {
ob_start();
eval("print $string[2];");
$return = ob_get_contents();
ob_end_clean();
return $return;
}
function eval_html($string) {
$string = preg_replace_callback("/(<\?=)(.*?)\?>/si",
"eval_print_buffer",$string);
return preg_replace_callback("/(<\?php|<\?)(.*?)\?>/si",
"eval_buffer",$string);
}
?>
David Schumann
04-Nov-2003 01:17
To evaluate math expressions (multiply, divide, addition, subtraction, percentages), use the following function, based on Taras Young's 'evalsum' function posted earlier:
function matheval($equation){
$equation = preg_replace("/[^0-9+\-.*\/()%]/","",$equation);
$equation = preg_replace("/([+-])([0-9]+)(%)/","*(1\$1.\$2)",$equation);
// you could use str_replace on this next line
// if you really, really want to fine-tune this equation
$equation = preg_replace("/([0-9]+)(%)/",".\$1",$equation);
if ( $equation == "" ) {
$return = 0;
} else {
eval("\$return=" . $equation . ";");
}
return $return;
}
You could easily extend this to include exponents, square roots, or really any other mathematical function. I use it in a 'price each' field on a purchase order form. The user can type in '$10.00-25%' and get 7.50 as the result.
lclkk at urbanvagabond dot net
11-Sep-2003 01:04
You can use eval() to pass variable-length parameter lists to arbitrary functions by using func_get_args() to build the required code. This approach can sometimes be preferable to using an array. The example below defines a function capable of instantiating objects whose constructors expect different numbers of parameters.
<?php
function classFactory($classname)
{
$code = "return new {$classname}(";
if (func_num_args() > 1) {
$params = array_slice(func_get_args(),1);
$c = count($params);
for($i=0;$i<$c;++$i) {
if ($i>0) {
$code .= ',';
}
$code .= '$params[' . $i . ']';
}
}
$code .= ');';
return eval($code);
}
class Foo
{
function Foo($arg1,$arg2,$arg3)
{
echo "I am Foo, I expect 3 arguments...\n";
echo "arg1 = $arg1\n";
echo "arg2 = $arg2\n";
echo "arg3 = $arg3\n\n";
}
}
class Bar
{
function Bar($arg1)
{
echo "I am Bar, I expect 1 argument...\n";
echo "arg1 = $arg1\n\n";
}
}
$myFoo = classFactory('Foo',100,'moose',array(1,2,3));
$myBar = classFactory('Bar',4564);
?>
G Systemacher
14-May-2003 11:10
An example of eval within a function within a class sitting on PEAR DB whose purpose is to push onto a result array named: result_ appended with a parameter key.
function set_result_array($fn_request_key = '[DEFAULT]', $fn_result) {
$target_array_string = 'result_'.$fn_request_key;
// eval ("global \$\$target_array_string;");
eval("\$target_array =& this->\$target_array_string;");
if (!is_array($target_array)) { $target_array = array(); }
return array_push($target_array, $fn_result);
}
What does this illustrate? An example of using eval to create a reference to an object member by reference (=&).
The eval ("global ....) line is commented out as I couldn't get this to work for some reason.
Smooth
28-Jan-2003 02:53
/* It seems that eval() won't return by reference: */
function &get_ref ($var) {
...
return $reference;
}
/* The following code returns a parse error */
/* (expecting `T_NEW' or `T_STRING' or `T_VARIABLE' or `'$'') */
$r =& eval ('return get_ref ($v);');
/* But thinking "inside the box" you can always do this... */
eval ('$r =& get_ref ($v);');
(I'm using PHP Version 4.2.3)
Matt Flaherty
03-Jan-2003 10:48
With regard to the comments from Jan 8 and 9 2002, some problems may still occur that can be eliminated by adding whitespace as below:
eval (' ?>' . $string . '<?php ');
However it is important to realise that you must not comment out a line such as this. The delimiters will still be parsed, which would produce unexpected results and probably errors. Perhaps better to do something like this, which should have no trouble:
//eval (' ?' . '>' . $string . '<' . '?php ');
barry at sanyuan dot com dot au
09-Dec-2002 08:03
Almost driving me to the ends of insanity i found the scripts above for eval html with php inside would not work on strings like :
<?php for($i=1; $i < 7; $i++) { ?>
<?php echo $i; ?>
additional html here
<? } ?>
In the end, as another option for executing string with both html and php was with tmpnam... eg.
$tmpfname = tempnam ("/tmp", "FOO");
$fp = fopen($tmpfname, "w");
fwrite($fp, $CONTENT[tpl_body]);
fclose($fp);
include($tmpfname);
unlink($tmpfname);
It works perfectly for me and is an alternative to eval for php and html.
olivier at revenu dot nom dot fr
08-Jul-2002 11:44
Here an improved function of evalHTML discussed above (see brandon@louish.net or nathan vonnahme).
I do some bench with a multi-line string contain php code <?echo "hello" ?> :
for 1200 eval/replace => proceed 10 times faster
for 12 eval/replace => proceed 3 times faster
function also support both <? and <?php style... enjoy !
** BEGIN **
function eval_buffer($string) {
ob_start();
eval("$string[2];");
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
function eval_html($string) {
return preg_replace_callback("/(<\?php|<\?)(.*?)\?>/si",
"eval_buffer",$string);
}
** END **
?>
for older php version (< 4.0.5), it also possible to do it with preg_replace but it's a little slower (20 %) :
** BEGIN **
function eval_buffer($string) {
ob_start();
eval(stripslashes("$string;"));
$string = ob_get_contents();
ob_end_clean();
return $string;
}
function eval_html($string) {
return preg_replace("/(<\?php|<\?)(.*?)\?>/sie",
"eval_buffer('\\2')",$string);
}
** END **
nospam at 1111-internet dot com
28-Feb-2002 08:12
Understanding the following concept should help users of the eval function:
It appears that the first thing eval does internally before actually eval-ing is to sandwich the argument between the strings "<?php " (note the trailing space) and "?>" (with no spaces). This accounts for the following behavior (and some of the behaviors already cited by other users):
<?php
$ques="?";
$php_open="<${ques}php";
$php_close="${ques}>";
$text_string="Text string";
eval("$text_string");
eval("$php_close$text_string$php_open");
eval("$php_close$text_string$php_open "); $code_string="echo 'Code string';";
eval("$code_string");
eval("$php_close$code_string$php_open");
eval("$php_close$code_string$php_open "); $code_string_with_php_tags="$php_open echo 'Code string'; $php_close";
eval("$code_string_with_php_tags");
eval("$php_close$code_string_with_php_tags$php_open");
eval("$php_close$code_string_with_php_tags$php_open "); ?>
Interestingly, the implicit eval done in the preg_replace function with the "e" switch seems to have a separate set of rules - sandwiching the replace argument between "return " and ";" (after running addslashes on any match references in the replace string - but I digress) before running the eval on it...
spam at seahat dot com
24-Jan-2002 08:01
One thing I didn't see mentioned that I had to figure out myself (which may be different in the latest version of php) is you must declare your globals in the eval()'d text if you want to get some vars from the source you are calling from. Just think of it as a function in its own file (despite any lack thereof).
die | exit |  | | | Last updated: Thu, 19 May 2005 |
| |