Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Miscellaneous Functions : eval

eval

Evaluate a string as PHP code (PHP 4, PHP 5)
mixed eval ( string code_str )

Example 1354. 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.

Related Examples ( Source code ) » eval





Code Examples / Notes » eval

mahaixing

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 "
";
//Here output 'someclass'
$instance->show();


nova912

Well let me just start off by saying that eval(); confused the heck out of me untill I read that you can use Return.
This will help anyone who wants to "Inject" code into an IF statement. My example is a survey site, some questions are required, some are only required if others are checked. So let me share with you my dynamic script and show you how I was able to make a Dynamic IF Statement.
The code below had been altered to be understandable.
<?php
$survey_number = 3 // The third survey. (Out of 10 Surveys)
$rq[3] = array(1,2,3,4,5,6,8,9,11,13,15,17,19,20); // Required Questions  for Survey 3 - Some of these can not be "NULL" (not NULL) or they will stop the script from going any further. (In my script I replaced any questions that were not answered with "NULL" using a for loop based on the number of questions in the survey)
$aa[3][4] = ' && '.$q[3].' == "1"'; // Added Arguments - 3 = Survey 3's Arguments, 4= Argument belongs to question 4, $q[1-20] (20 Questions total in this case.
//HERE IS THE DYNAMIC IF STATEMENT
$count = count($rq[$survey_number]);
for ($i=0;$i< $count;$i++)
{
$if_statement = '$q['.$rq[$survey_number][$i].'] == "NULL"';
if(isset($aa[$survey_number][$rq[$survey_number][$i]]))
{
$if_statement .= $aa[$survey_number][$rq[$survey_number][$i]];
}
if(eval("return ".$if_statement.";"))
{
echo $rq[$survey_number][$i].': Is NULL and IS NOT ok.
';
}
else
{
echo $rq[$survey_number][$i].': Is NULL and IS ok.
';
}
}
?>
In my experiance with this the Added Argument needs to have an actual value inplanted into the string, it did not work by just putting $q[3], i had to use '.$q[3].' to place the value of question 3 in the string.
I hope this help someone, I spent so much time trying to figure this out and want to share how something this simple is done.
Thank you.


privat

Using the html_eval() some notes above I experienced problems related to *dirty* html. This function is less critical:
function html_eval2($string) {
 return preg_replace_callback("/<\?php(.*?)\?>/","my_eval",$string);
}
function my_eval($arr) {
 return eval($arr[1]);
}
Timo


jtraenkner

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();'.
   '}');
?>


andrejkw

To use eval output as a variable without the user seeing the output, use this:
<?php
ob_start();
eval("whatever you want");
$eval_buffer = ob_get_contents();
ob_end_clean();
echo $eval_buffer;
?>
Everything that eval produces will now be stored inside $eval_buffer.


onlyphp

To simulate the register_globals setting in php.ini, you must put it in the top of your php page:
function rg() {
 $ar = array($_POST, $_GET, $_SESSION, $_SERVER);
 foreach($ar as $ar_) {
   foreach($ar_as $key => $value) {
     eval("\$" . $key . " = \"" . $value . "\";");
   }
 }
}


samme

To Nova912
Your code really made me dizzy.
Never ever do something like.
<?php
$if_statement = 'wierd && boolean == expression';
if (eval("return ".$if_statement.";")) {
 do_stuff();
}
?>
but rather.
<?php
if (wierd && boolean == expression) {
 do_stuff();
}
?>
Ok thanks bye.


matt

to load a php file to a variable then execute it, try this
<?php
$code=file_get_contents("file.php");
$code=str_replace('<'.'?php','<'.'?',$code);
$code='?'.'>'.trim($code).'<'.'?';
eval($code);
?>
using < ?php within eval does not work, but < ? does. in case there is html in the file loaded, the script doesn't remove the < ?php and ? >, but insted adds ? > and < ? around the code loaded from the file. it's simple and works very well. I also broke up the tags in the 3rd and 4th lines of code to keep from having problems if the lines are commented out.


david schumann

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.


joeri

This is a variation on the contribution of Matt's note, to load a php file into a variable and then evaluate it (which works perfect).
This snippet does almost te same, but instead of sending it back to the browser, it sends it back to a variable.
<?PHP
function phpWrapper($content) {
ob_start();
$content = str_replace('<'.'?php','<'.'?',$content);
eval('?'.'>'.trim($content).'<'.'?');
$content = ob_get_contents();
ob_end_clean();
return $content;
}
$content = file_get_contents('feedback.php');
$content = phpWrapper($content);
// $content will now contain your evaluated code :)
?>


avenger

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.");
?>
</body></html>


nick - safirex

This function will take any combination of HTML and (properly opened and closed)PHP that is given in a string, and return a value that is the HTML and the RESULT of that PHP code and return them both combined in the order that they were originally written.
This is a correction of an earlier script.
In the earlier varsion the preg_replace_callback search pattern was incorrect and wouldn't allow line breaks within the HTML sections.
I have also included a line to change shorthand <?= $var ?> to <? echo $var; ?>
This code is basicaly a version of the 'include' function which can be run on variables instead of files. Optionaly output can be captured using output buffering.
<?
function eval_mixed_helper($arr){
 return ("echo stripslashes(\"".addslashes($arr[1])."\");");
 }
function eval_mixed($string){
 $string = "<? ?>".$string."<? ?>";
 $string = preg_replace("/<\?=\s+(.*?)\s+\?>/", "<? echo $1; ?>", $string);
 $string = str_replace('?>', '', str_replace( array('<?php', '<?'), '', preg_replace_callback( "/\?>((.|\n)*?)<\?/","eval_mixed_helper",$string) ) );
 return eval($string);
 }
// output to browser
eval_mixed($string);
// output to variable
ob_start();
eval_mixed($string);
$final_html = ob_get_clean();
?>


admiral

This function will take any combination of HTML and (properly opened and closed)PHP that is given in a string, and return a value that is the HTML and the RESULT of that PHP code and return them both combined in the order that they were originally written.
I tried using both the eval_html(gave me carp about using 's and "s in the HTML) and html_eval2(gave me the results of the PHP first, then all of the HTML afterwards) posted by the other users on this function's notes, but for some reason, neither of them would really work the way I had understood that they would work,(or in the case of some of my code, work at all)
So I combined the best of what I saw in both, and created eval_html3
<?php
function my_eval($arr) {
return ('echo stripslashes("'.addslashes($arr[0]).'");');
}
function eval_html3($string) {
$string = '<?php ?>'.$string.'<?php ?>';
$string = str_replace( '?>', '', str_replace( array( '<?php', '<?' ), '', preg_replace_callback( "/\?>(.*?)(<\?php|<\?)/", "my_eval", $string ) ) );
return eval($string);
}
?>
Good luck!


jasperbg

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.


aleosha

There's a minor mistake in example that shows how to correctly use EVAL with IF statements.
Instead of
$str="\$refer=&\$total".$i.";";
eval($str);
Wich just puts value "total2" in your $refer variable, you should  use
$str="\$refer=&\$$total".$i.";";
This one will create the real referrer to the value of $total2 (5, in our case).


burninleo

The only way to retreive information on parse errors in eval'd code seems to be the output buffering.
<?PHP
// Append a return true to php-code to check on errors
$code.= "\nreturn true;";
// Send any output to buffer
ob_start();
// Do eval()
$check = eval($code);
$output = ob_get_contents();
ob_end_clean();
// Send output or report errors
if ($check === true) {
 echo $output;
} else {
 // Manually parse output for errors and
 // generate usable information for the user
 // especially content of error-lines.
 $pattern = '/^\s*Parse error\s*:(.+) in (.+) on line (\d+)\s*$/m';
 etc ...
}


sarangan thuraisingham

The eval function can be misused for Cross Site Scripting(XSS) as well. Les say we have this very trivial page that allows a user to enter a text and see it formated using different styles. If the site designer was lazy and used eval function to come up with somethig like this:
<?php
$mytxt = $_GET["text"];
$strFormats = array( '<h1>$mytxt</h1>',
                     '<h2>$mytxt</h2>',
                     '<span class="style1">$mytxt</span>'); //so on
foreach ($strFormats as $style){
   eval("echo $style;");
}
?>
This page could be a target for XSS, because user input is not validated. So the hacker could enter any valid PHP commands and the site will execute it. Imagine what could happen if the injected script reads files like config.php and passed it to the hacker's site.
If the file permissions are not set correctly, the injected script could modify the current script. A form's action parameter can be set to a hacker's site or worse every transaction could be secretly posted to another website from within the server. Injected script could be something like this:
<?php
$filename=basename($_SERVER['PHP_SELF']);
$fp = fopen($filename, "a");
$str = echo "<!-- XSS Vulnerability-->"; // could be any PHP command
fwrite($fp, $str);
fclose($fp);
?>
The golden rule is don't trust the user. Always validate data from the client side.


ben grabkowitz

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();');


kai dot chan

Since JSON started becoming popular. I've started applying the same idea to PHP arrays. Its an alternative to using XML or CSV. For example:
<?php
$from_external_source = '( "a" => "1", "b" => array( "b1" => "2", "b2" => "3" ) )';
eval( '$external_source_as_array = array'.$from_external_source.';' );
if ( is_array( $external_source_as_array ) ) {
// now you can work with the external source as an array
print_r( $external_source_as_array );
}
?>
It can be less verbose than XML, but provide more meta data than CSV, and unlike CSV, data ordering is not an issue.
I used it when I wanted to store log data externally in a text file.
Kai


udo dot schroeter

Safer Eval
eval() is used way to often. It slows down code, makes it harder to maintain and it created security risks. However, sometimes, I found myself wishing I could allow some user-controlled scripting in my software, without giving access to dangerous functions.
That's what the following class does: it uses PHP's tokenizer to parse a script, compares every function call against a list of allowed functions. Only if the script is "clean", it gets eval'd.
<?php
 class SaferScript {
   var $source, $allowedCalls;
   
   function SaferScript($scriptText) {
     $this->source = $scriptText;
     $this->allowedCalls = array();      
   }
 
   function allowHarmlessCalls() {
     $this->allowedCalls = explode(',',
       'explode,implode,date,time,round,trunc,rand,ceil,floor,srand,'.
       'strtolower,strtoupper,substr,stristr,strpos,print,print_r');    
   }
   
   function parse() {
     $this->parseErrors = array();
     $tokens = token_get_all('<?'.'php '.$this->source.' ?'.'>');    
     $vcall = '';
     
     foreach ($tokens as $token) {
       if (is_array($token)) {
         $id = $token[0];
         switch ($id) {
           case(T_VARIABLE): { $vcall .= 'v'; break; }
           case(T_STRING): { $vcall .= 's'; }
           case(T_REQUIRE_ONCE): case(T_REQUIRE): case(T_NEW): case(T_RETURN):
           case(T_BREAK): case(T_CATCH): case(T_CLONE): case(T_EXIT):
           case(T_PRINT): case(T_GLOBAL): case(T_ECHO): case(T_INCLUDE_ONCE):
           case(T_INCLUDE): case(T_EVAL): case(T_FUNCTION): {
             if (array_search($token[1], $this->allowedCalls) === false)
               $this->parseErrors[] = 'illegal call: '.$token[1];
           }            
         }
       }    
       else
         $vcall .= $token;
     }
     
     if (stristr($vcall, 'v(') != '')
       $this->parseErrors[] = array('illegal dynamic function call');
     
     return($this->parseErrors);
   }
 
   function execute($parameters = array()) {
     foreach ($parameters as $k => $v)
       $$k = $v;
     if (sizeof($this->parseErrors) == 0)
       eval($this->source);
     else
       print('cannot execute, script contains errors');
   }  
 }
?>
Usage example:
<?php
 $ls = new SaferScript('horribleCode();');
 $ls->allowHarmlessCalls();
 print_r($ls->parse());
 $ls->execute();
?>
Of course it is not entirely safe, but it's a start ;-)


alerante

Regarding the problem posted by jkuckartz1984 at hotmail dot com: you must return a value in the eval'd code block, so the code really should be
<?php
if (eval("return \$total".$i.";")) {
  echo "eval: total2 is full
";
} else {
  echo "eval: total2 is empty
";
}
?>
However, this is really a job for "variable variables" < http://php.net/variables.variable >:
<?php
$varname = "total$i";
if ($$varname) {
  [...]
}
?>


apmuthu

Ref: Nick - SafireX, TfM, Nick Johnson - Pixelrific
Generic eval function
Replace the line:-
$string = preg_replace("/<\?=\s+(.*?)\s+\?>/", "<? echo $1; ?>", $string);
with
$string = preg_replace("/<\?=\s*(.*?)\s*\?>/", "<? echo $1; ?>", $string);
The "\s*" in the two places will enable 0 or more white spaces to exist after the "=" instead of the existing "\s+" which enables only 1 or more white spaces.
Also instead of using the eval function in the return statement of the function, it would be better to return only the string ready to perform eval and then do the eval in the main program where the scope and visibility of variables are known.


karig

OK, here's what I've found to work for me:
Let's say I have a string like this, pulled from a much larger file:
$text = "

The following is generated by PHP:\n"
. '<?php $a = 6; $b = 4; $c = $a + $b; '
. 'echo "

Variable c = $c\n"; ?>'
. "

This is just more text.\n";
Doing this just echoes the PHP code (so a visitor can actually read it by viewing the web page's source) instead of executing it:
echo $text;
I wanted to have the PHP code in the text executed, so that the /result/ is echoed, and the code itself is not. Happily, all I needed to do to get this to work for me was this:
ob_start();
eval ('?>' . $text);
$text = ob_get_clean();
// Do whatever else you want with $text before outputting it
echo $text;
That little '?>' prepended to $text (suggested by a previous note here) seems to be the key. Note that I DON'T append a corresponding '<?php' to $text, as a previous note suggested; I tried that, and I got an error. But I've found that "eval ('?>' . $text);" works:
---- OUTPUT ----
The following is generated by PHP:
Variable c = 10
This is just more text.
---- HTML REVEALED IN WEB-PAGE SOURCE ----


The following is generated by PHP:


Variable c = 10


This is just more text.


tfm

Nick, I needed to replace "<?php" with "<?" before feeding the string to preg_replace_callback to make it work with recursive includes. Nice code anyway :)

jkuckartz1984

Might you have to do eval in if statements, you will find it's quite some task to make it work.
The only way to make it work is to make a reference to the eval'd variable. This example will show the different usage of eval in if-statements. It simply becomes clear that an eval() in an if() is not working as you want to.
<?php
$total2=5;
$total3=0;
$i=2;
if (eval("\$total".$i.";")) {
echo "eval: total2 is full
";
} else {
echo "eval: total2 is empty
";
}
// returns "empty"
// eval without the ";" will generate a warning
$str="\$refer=&\$total".$i.";";
eval($str);
if ($refer) {
echo "eval: total2 is full
";
} else {
echo "eval: total2 is empty
";
}
// returns "full"
?>


alexandrebr

Like said before, use of 'eval' is not recommended, by the security issues.
A good use of eval, is to test your codes without having to create/save files on the hard drive.
You may want to create the script below, and send to your server, to help you to manage your database, for example...
<?
if(isset($_POST["code"])){
 $code = get_magic_quotes_gpc()?
   stripslashes($_POST["code"]):
   $_POST["code"];
 eval("?>".$code);
}
else{
 echo "<form method='post' action='eval.php'>";
 echo "<textarea name='code'></textarea>
";
 echo "<input type='submit' value='Test the code above'>";
 echo "</form>";
}
?>
With this, you can easily exec PHP codes on your site, without having to connect to the FTP and uploading files.....
Even tests with extensions like PHP_GD are allowed.
WARNING: If you wish to use the example above, PUT A PASSWORD PROTECTION! The function EVAL gives fully access to your site, so be careful.


12-jul-2004 05: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


sean

kai dot chan, that code is rather unnecessary.  Aside from the huge security risk (the same risk exists for naive JSON implementations, and good ones do not use the eval() construct), PHP already has a means of safely encoding/decoding arrays: serialize() and unserialize().
Not to mention that PHP now has JSON functions, so you can just the regular JSON format itself.  Still safer that way.


aoeuid

Just as a reply to 'evildictaitor', eval() obfuscation can be of use use against script kiddies, or people with little free time if implemented more intelligently.
And by more intelligently I mean more randomly, do perhaps a hundred iterations and randomly choose the obfuscation method every iteration. Doing rot13 with base64 once, then something from Mcrypt() and so on. Might take its toll on performance, but atleast isn't _that_ easily solved by eval->print :)
Of course, obfuscation isn't really a way to securing your code, but might work if one's in a hurry and doesn't have anything else better.


nick

Just a quick note on the functions below that use 'eval_mixed_helper' using add/remove slash do not work if the content includes PHP like code. Using base64 encode/decode solves this.
E.g.
function eval_mixed_helper($arr)
{
return ('echo base64_decode("'.base64_encode($arr[1]).'");');
}


1413

Just a note when using eval and expecting return values - the eval()'ed string must do the returning.  Take the following example script:
<?php
function ReturnArray()
{
 return array("foo"=>1, "bar"=>2);
}
$test = eval("ReturnArray();");
print("Got back $test (".count($test).")\n");
$test = eval("return ReturnArray();");
print("Got back $test (".count($test).")\n");
?>
You will get back:
Got back  (0)
Got back Array (2)
This ran me afoul for a little bit, but is the way eval() is supposed to work (eval is evaluating a new PHP script).


mat.wilmots

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


user

It's possible to catch fatal errors using register_shutdown_function().

amedeo

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
       )
)


macronesia

Instead of using eval for template logic, use str_replace to replace variables with proper code, such as XHTML.

nick johnson - pixelrific

In reference to Nick's functions below (which didn’t work for me as is) and TfM's comment, this is fixed with a simple change to the pattern used by preg_replace_callback.  The pattern should be changed from
/\?>((.|\n)*?)<\?/
to
/\?>((.|\n)*?)<\?(php)?/
Making that small change will remove a "php" that is leftover in the string to be evaled, which eval trips on and complains about.


zcox522

If you send headers after you call the eval() function, you may get this error:
PHP Error: (2) Cannot modify header information - headers already sent by (output started at something...)
In this case, surround your call to eval() with calls to some ob functions:
<?php
$eval = "some code you want to execute";
ob_start();
eval($eval);
ob_end_clean();
?>


dale kern, salt lake city

If you are trying to get eval()  to run a string as if it were from an include file, try this:
eval("?>".$string);
Eval starts in PHP Script mode, break into html mode first thing and you're done.


brettz9 a/- yah00 do/- com

I was trying to build a multidimensional array to an unknown dimension (within a loop or "while") and found that eval is, as far as I can tell, the only simple way to solve the problem.
<?php
$arr = array(2,
                array("v", "q", 5,
                                   array(5, 8, "g"),
                                                     "x"));
$i=3;
$key1 = "[1]";
$key2 = "[".$i."]"; // E.g., could build this conditionally within a loop
$key3 = "[2]";
$keys = $key1.$key2.$key3; // Can add as many keys as needed (could be done instead via a loop with repeated calls to .= )
print $arr{$keys}; // This does not work
print $arr[$keys]; // This also does not work
// However...
eval("\$value = \$arr{$keys};");
print $value; // Correctly prints "g"
?>


jphansen

I used eval() to restore a user's session data. I stored $_SESSION to a field in a database as
<?
addslashes(var_export($_SESSION, TRUE))
?>
To restore it, I executed this code:
<?
eval("\$_SESSION = $session;");
// $session being the first line of code above
?>
Voila! Session restored.
Without eval(), $_SESSION = $session would have resulted in $_SESSION being a string instead of an array.


sadi

I m going to give you my recent exploration about eval. I think you dont need all those complex functions using regex to work HTML in your code. when ever you call eval(), php thinks that it is within <? ?> tags. so all the problem rises. to solve the problem just close your php tag at first of the HTML string, then write the HTML string and then start the php tag.
this is some thing like:
<?php
$teststr="?><html><body>this is the test</body></html><?php";
eval($teststr);
?>
i think this will work for you. at least this worked for me. if you find any problem with this please reply


critmas

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


olivier

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 **


nicolas_rainardnospam

Ever whished to evaluate an external file as a PHP script and get the result as string?
Exemple: you'd like to get the contents (and all PHP output) of a (text|XML|HTML) file after having processed whatever PHP inclusion it may contain, to further process these contents.
You can do this:
<?php
$str = compile('file_to_process');
$str = do_more_things_with($str);
echo $str;
function compile($file) {
ob_start();
require $file;
return ob_get_clean();
}
?>
It *should* work without problem if the caller script already uses output buffering, since output buffers are stackable (not tested yet).


jurgen

eval() is used to protect (read: hide) source code. A well known way to encrypt some php code is security through obscurity.  Someone used eval(base64_encode(".....")); - which basically had 10-16 nested calls to eval(base64_encode()) inside the data.
E.g.
<?
eval(gzinflate(base64_decode('AjHRawIHG1ypUpudV.....')));
?>
However this can be decoded in this way:
<?
echo "\nDECODE nested eval(gzinflate()) by DEBO Jurgen <jurgen@person.be>\n\n";

echo "1. Reading coded.txt\n";
$fp1      = fopen ("coded.txt", "r");
$contents = fread ($fp1, filesize ("coded.txt"));
fclose($fp1);

echo "2. Decoding\n";
while (preg_match("/eval\(gzinflate/",$contents)) {
$contents=preg_replace("/<\?|\?>/", "", $contents);
eval(preg_replace("/eval/", "\$contents=", $contents));
}

echo "3. Writing decoded.txt\n";
$fp2 = fopen("decoded.txt","w");
fwrite($fp2, trim($contents));
fclose($fp2);
?>


tom

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);
}
?>


f dot boender

Errors that occur in evaluated code are hard to catch. burninleo at gmx dot net posted some code below that will buffer the output of the evaluated code and search the output for errors. Another way you can do this would be using a custom error handler that's only in effect during the eval() of the code. A very (very) crude example:
<?php
$errors = array();
function error_hndl($errno, $errstr) {
   global $errors;
   $errors[] = array("errno"=>$errno, "errstr"=>$errstr);
}
function evale ($code) {
   global $errors;
   $errors = array();
   $orig_hndl = set_error_handler("error_hndl");
   eval($code);
   restore_error_handler();
}
evale('print("foo" . $bar);'); // Undefined variable: bar
var_dump($errors);
//fooarray(1) {
//  [0]=>
//  array(2) {
//    ["errno"]=>
//    int(8)
//    ["errstr"]=>
//    string(23) "Undefined variable: bar"
//  }
//}
?>
This will however not catch syntax errors in the code you're trying to eval. This can cause your script to stop with a fatal error inside the eval(). You can catch syntax errors using the Parsekit PECL extension. The parsekit_compile_string() function will try to compile a piece of PHP code and will catch syntax errors if they occur. To extend the earlier piece of code:
<?php
$errors = array();
function error_hndl($errno, $errstr) {
   global $errors;
   $errors[] = array("errno"=>$errno, "errstr"=>$errstr);
}
function evale ($code) {
   global $errors;
   $errors = array(); // Reset errors
   $orig_hndl = set_error_handler("error_hndl");
   if (parsekit_compile_string($code, &$errors, PARSEKIT_QUIET)) {
       eval($code);
   }
   restore_error_handler();
   if (count($errors) > 0) {
       return(false);
   } else {
       return(true);
   }
}
if (!evale('print("foo . $bar);')) { // syntax error, unexpected $end (no closing double quote)
   var_dump($errors);
}
?>
(NOTE: Please do not use the code above directly in your program. It's merely a proof-of-concept).


arnico

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


evildictaitor

Don't use eval to obfruscate code. Don't. No. stop. Never. Ever. It's so incredibly easy to decode, it's not worth it.
<?php
 $someAwfulObfrsucatedCode = "1209;nlu[qer;j12.n";
 function someImpressiveDeobfruscationRoutine($string){
   ..somecode..
   return $realCode;
 }
 eval(someImpressiveDeobfruscationRoutine($someAwfulObfruscatedCode));
?>
To decode, try replacing eval with echo, and voila, your code in-tact.
Examples of misguided attempts at securing code with eval include base64[en|de]code and url[en|de]code, but regardless of your encoding/decoding skills and functions, replacing eval with echo will get the code back in all functions of this sort.


mark aufflick mark

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);
}
?>


francois

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!


g systemacher

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.


barry

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.


pierrotevrard

A wonderful world of eval() applications
You certainly know how to simulate an array as a constant using eval(), not ? See the code below:
<?php
if( ! defined('MY_ARRAY') )
{
 define( 'MY_ARRAY' , 'return ' . var_export( array( 1, 2, 3, 4, 5 ) , true ) . ';' );
}
?>
And far, far away in your code...
<?php
$my_array = eval( MY_ARRAY );
?>
But the grandeur of eval is when you use it to customize some method of a class :
<?php
if( ! class_exists( 'my_class' ) )
{
 class my_class
 {
   //private propreties
   var $_prop;
   var $_custom_check = 'return true;'; //of course, I want a default check code that return true
   //PHP4 constructor
   function my_class()
   {
     $this -> _prop = eval( MY_ARRAY );
   }
   function customize_check( $code )
   {
     $this -> _custom_check = $code;
   }
   function check( $val )
   {
     return eval( $this -> _custom_check );
   }
 }
}
$my_class = new my_class();
$check = 'return in_array( $val , $this -> _prop , true );';
$my_class -> customize_check( $check );
print '<pre>';
if( $my_class -> check( 1 ) )
{
  echo '1 is checked as true.' . "\n";
}
else
{
  echo '1 is checked as false.' . "\n";
}
//show: 1 is checked as true.
if( $my_class -> check( '1' ) )
{
  echo '"1" is checked as true.' . "\n";
}
else
{
  echo '"1" is checked as false.' . "\n";
}
//show: "1" is checked as false.
print '</pre>';
?>
The application of eval() using propreties of a class gives you so much possibilities...
Of course, combinate with a safer eval code, will be better but if you use it only in your code ( for framework project by example ) that's note necessary...
Have fun.


slimshady451

A simple function to eval sum user's code for maths.
<?php
function strtonum($str)
{
$str = preg_replace('`([^+\-*=/\(\)\d\^<>&|\.]*)`','',$str);
if(empty($str))$str = '0';
else eval("\$str = $str;");
return $str;
}
//this
echo strtonum("(1<<10)*10"),'<br />';
echo strtonum("10*9.78"),'<br />';
//will output
10240
97.8
?>


jesse

a cool way to use eval is to convert strings into variable names.
this is a subsitute for using arrays.
look at this code:
<?php
for($a=1; $a<=5; $a++){
   eval("$"."variable".$a."=".$a.";");
}
?>
this will create variables called variable1, variable2, and so on, that are equal to 1, 2, and so on.
i recently used this to help a friend make a Flash game that sent variables like that to PHP.


license_to_il

// the array in my code
$my_ar = array(2,3,4,5);
// eval in code or pulled from db
eval("print_r(\$my_ar);");
output:
Array ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 )


smooth

/* 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)


the dank

$foo1 = "the good,
";
$foo2 = "the bad,
";
$foo3 = "the ugly.";
for ($i=1; $i <=3; $i++)
{
    eval("\$_SESSION['myVar$i'] = \$foo".$i.";");
}
//use below to show what's in session:
echo "<h3>SESSION</h3>";
echo "<table border=1 width=50%>";
echo "<tr bgcolor=\"#3399FF\">";
echo "<td><b><font color=\"#FFFFFF\">Variable Name</font></b></td>";
echo "<td><b><font color=\"#FFFFFF\">Value</font></b></td></tr>";
while(list($key, $val) = each($_SESSION))
{
echo "<tr><td>$key</td><td><b>$val</b></td></tr>";
}
echo "</table>";
die();
/*---------------------------------------------------------
Prints:
myVar1 the good,
myVar2 the bad,
myVar3 the ugly.
*/


info

"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.


npugh

"Also remember that variables given values under eval() will retain these values in the main script afterwards."
This line confused me for a moment.  What they mean is that if you modify a variable that was declared outside of the eval code from within the eval, it stays modified.  Of course.  
What it does _not_ do is make any newly created variables global, which is what I was worried about.  Variables created from inside an eval will retain the same scope as where the eval statement was called from (or lesser scope if they were created inside a function inside the eval, etc).
"If eval() is the answer, you're almost certainly asking the
wrong question." -- Rasmus Lerdorf, BDFL of PHP
It seems to me that eval is the only fix for the static class members + inheritance problem(as of PHP5).


jnavratil

"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." isn't strictly true as the eval can return a value through the side-effect of setting a variable.
<?php
function getValue()
{
return 123;
}
function testEval1()
{
eval('return getValue();');
}
function testEval2()
{
eval('$rslt = getValue();');
return $rslt;
}
function testEval3()
{
return eval('return getValue();');
}
function testEval4()
{
return eval('getValue();');
}
print '1:'.testEval1()."\n";
print '2:'.testEval2()."\n";
print '3:'.testEval3()."\n";
print '4:'.testEval4()."\n";
?>
results in...
1:
2:123
3:123
4:
In case 1, the eval returns the result to an uncaring caller (contra: case 3).  In case 2, the eval makes the result available through the side-effect of setting '$rslt'.  In case 4, 'eval' returns null to an apparently caring caller (contra: case 1).


Change Language


Follow Navioo On Twitter
connection_aborted
connection_status
connection_timeout
constant
define
defined
die
eval
exit
get_browser
__halt_compiler
highlight_file
highlight_string
ignore_user_abort
pack
php_check_syntax
php_strip_whitespace
show_source
sleep
sys_getloadavg
time_nanosleep
time_sleep_until
uniqid
unpack
usleep
eXTReMe Tracker