PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

exit> <die
Last updated: Fri, 01 Aug 2008

view this page in

eval

(PHP 4, PHP 5)

evalEvaluate a string as PHP code

Description

mixed eval ( string $code_str )

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 . To mix HTML output and PHP code you can use a closing PHP tag to leave PHP mode.

Also remember that variables given values under eval() will retain these values in the main script afterwards.

Parameters

code_str

The code string to be evaluated. code_str does not have to contain PHP Opening tags.

A return statement will immediately terminate the evaluation of the string .

Return Values

eval() returns NULL unless return is called in the evaluated code, in which case the value passed to return is returned. If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following code continues normally. It is not possible to catch a parse error in eval() using set_error_handler().

Examples

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.

Notes

Note: Because this is a language construct and not a function, it cannot be called using variable functions

Tip

As with anything that outputs its result directly to the browser, the output-control functions can be used to capture the output of this function, and save it in a string (for example).

Note: In case of a fatal error in the evaluated code, the whole script exits.

See Also



exit> <die
Last updated: Fri, 01 Aug 2008
 
add a note add a note User Contributed Notes
eval
marco at harddisk dot is-a-geek dot org
30-Jun-2008 07:44
eval does not work reliably in conjunction with global, at least not in the cygwin port version.

So:
<?PHP
class foo {
 
//my class...
}
function
load_module($module) {
  eval(
"global \$".$module."_var;");
  eval(
"\$".$module."_var=&new foo();");
 
//various stuff ... ...
}
load_module("foo");
?>

becomes to working:

<?PHP
class foo {
 
//my class...
}
function
load_module($module) {
  eval(
'$GLOBALS["'.$module.'_var"]=&new foo();');
 
//various stuff ... ...
}
load_module("foo");
?>

Note in the 2nd example, you _always_ need to use $GLOBALS[$module] to access the variable!
krisdover at hotmail dot com
28-Jun-2008 06:20
As critmas at hotmail dot com describes in an early posts, you can treat php tags as processing instructions if you need to evaluate some php in an xml/xhtml document, e.g. for templating. Note this is limited to simple php statement  evaluation and would not work with content which uses braces '{', you'll need to use include() for that. An example of this follows:

<?php
// setup a test document with some xhtml
$doc = new DOMDocument();
$doc->loadXML('<div><h1><?php echo $title; ?></h1><p><?php echo $msg; ?></p></div>');

// execute an xpath query to get all php scriplets
$xpath = new DOMXPath($doc);
$scripts = $xpath->query("descendant::processing-instruction(\"php\")");

// define our placeholder variables
$title = "foobar";
$msg = "a foo walks into a bar ...";

// fill in the template
foreach($scripts as $script){
 
ob_start();
  eval(
$script->data);
 
$result = ob_get_contents();;
 
ob_end_clean();
 
$script->parentNode->replaceChild($doc->createTextNode($result), $script);
}
echo
$doc->saveXML();
?>

The result is:

<?xml version="1.0"?>
<div><h1>foobar</h1><p>a foo walks into a bar ...</p></div>

Regards,
Kris
Anonymous
20-Jun-2008 07:11
In response to trukin at gmail dot com

A better version would be without using eval

<?php
function parseTemplate($template, $params=array()) {
 
extract($params);
 
ob_start();
  include
$template;
  return
ob_get_clean();
}
?>
trukin at gmail dot com
11-Jun-2008 05:58
The EVAL function can be used  as a fast Template system.

<?
function parseTemplate($template, $params=array()) {
  foreach (
$params as $k=>$v) {
     $
$k = $v;
  }
 
ob_start();
  eval(
"?>" . implode("", file($template)) . "<?");
 
$c = ob_get_contents();
 
ob_end_flush();
  return
$c;
}
?>

Example:
<?

echo parseTemplate("myTemplate.php", array('account'=>$row));
?>

and myTemplate.php can be like

<? foreach($account as $k=>$v) : ?>
  <?=$k?>: <?=$v?>
<?
endforeach; ?>
Juan
08-Jun-2008 03:23
in response to: Luke at chaoticlogic dot net

The Problem why your code using eval runs that slow is, that you are executing 10,000,000 times the eval construct instead executing it just once and including the loop inside the eval'd code:
<?php
// Like this it will run the eval function 10,000,000 times and
// thus the eval'd code 10,000,000 times too:
$increment=0;
$code="\$increment++;";
for (
$i=0;$i<10000000;$i++) {
    eval(
$code);
}

// Like this, the eval will only be executed once, but the code
// inside the loop inside the eval will be executed the
// 10,000,000 times as desired.
$increment=0;
$code='for ($i=0;$i<10000000;$i++) {
    $increment++;
}'
;
eval(
$code);

// Running the code with the loop inside the eval'd code made
// no measurable difference for me, compared to running it
// directly like this:
$increment=0;
for (
$i=0;$i<10000000;$i++) {
   
$increment++;
}
?>
The reason for your code being so much slower is simple:
Your Code does:
10,000,000 x eval()
10,000,000 x increment
My code does:
1 x eval()
10,000,000 x increment
As the eval construct is far more complex (I guess the parser has to be started every time) than the increment assgnment, it is obvious, that your code will need much more time to run.
michaelbehr70 at yahoo dot com
22-May-2008 05:38
I have read many of the note contributions to evaluate a database string that has both html and php code intermixed.  I have seen close to 8 different implementations.  I just wish to provide a warning.  NONE OF THEM ACTUALLY WORK.  People really should test their implementations prior to posting them on php.net
thiago dot pojda at gmail dot com
21-May-2008 03:15
Correcting previous comment from Ivan Zahariev, PHP did not recognize __FUNCTION__ in his example because of simple quotes (').

This code...

<?php
function user_func1() {
    echo
"User function name: ".__FUNCTION__."\n";
    eval(
"echo \"in eval(): User function name: ".__FUNCTION__."\n\";");
}
user_func1();
?>

... outputs:

User function name: user_func1
in eval(): User function name: user_func1
Ivan Zahariev
02-Apr-2008 11:09
It seems that the Magic constants (http://www.php.net/manual/en/language.constants.predefined.php) do NOT work in an eval()'ed code.

Probably because PHP substitutes these statically when it compiles the source code of your PHP script initially.

So the following will not work as expected:
<?php
function user_func1() {
    echo
"User function name: ".__FUNCTION__."\n";
    eval(
'echo "in eval(): User function name: ".__FUNCTION__."\n";');
}
?>

Calling user_func1() will output:
  User function name: user_func1
  User function name:
Luke at chaoticlogic dot net
02-Apr-2008 10:26
I thought it was pertinent to demonstrate just how slow the eval() function is when compared to pre-parsed code, so I wrote this.

In my case, it took 54 seconds to execute the code 100,000,000 times through eval(), and only 4 seconds with pre-parsed code.
<?php
//establish a blank integer
$increment=0;

//establish the code to be executed
//one hundred million times
$code="\$increment++;";

//remember the time this test started
$started=time();

//execute $code on hundred million times
for ($i=0;$i<10000000;$i++) {
    eval(
$code);
}
//find out how long it took, in
//seconds
$ended=time();
$spent=$ended-$started;

//tell the user this
print "Eval()ed code took $spent seconds to execute 100,000,000 times.\n";

//re-establish that same blank integer
$increment=0;

//remember the time this second test
//started
$started=time();

//execute the test again, with
//pre-parsed code
for ($i=0;$i<10000000;$i++) {
   
$increment++;
}
//find out how long it took, in
//seconds
$ended=time();
$spent=$ended-$started;

//tell the user this
print "Pre-parsed code took $spent seconds to execute 100,000,000 times.\n";
?>
I wish there was some way to parse code, store the pre-parsed binary in a variable, and then tell PHP to execute that variable as if it was part of the program.
Ipseno at yahoo dot com
25-Feb-2008 07:24
If you attempt to call a user defined function in eval() and .php files are obfuscated by Zend encoder, it will result in a fatal error.

Use a call_user_func() inside eval() to call your personal hand made functions.

This is user function
<?php

function square_it($nmb)
{
    return
$nmb * $nmb;
}

?>

//Checking if eval sees it?
<?php

$code
= var_export( function_exists('square_it') );

eval(
$code );    //returns TRUE - so yes it does!

?>

This will result in a fatal error:
PHP Fatal error:  Call to undefined function square_it()
<?php

$code
= 'echo square_it(55);' ;

eval(
$code );

?>

This will work
<?php

$code
= 'echo call_user_func(\'square_it\', 55);' ;

eval(
$code );

?>
greg at freephile dot com
05-Feb-2008 10:44
Use the 'e' pattern modifier to evaluate the replacement as PHP code during substitution in order to put variables in a message template

<?php
$template
= '

This is a template with $foo tokens
It also has {new} tokens
'
;

echo
"<pre>$template</pre>";

$foo = blue;
$new = Smarty;

$message = preg_replace('/\\$([\w]+)/e', '$\\1', $template);
$message = preg_replace('/\{([^}]*)}/e', '$\\1', $message);

echo
$message;
?>

This is a template with $foo tokens
It also has {new} tokens

This is a template with blue tokens It also has Smarty tokens
Elie B.
07-Dec-2007 12:27
Nicolas Rainard suggested using ob_get_clean() to get the results, and get back to the rest of your code. However, I'd like to clarify that your application may or may not already rely on output buffering mechanisms. In all cases, you should not interfere with the rest of your application without a strong will (and a good reason) to do so.

Enabling output buffering is fine for small scopes (function wide for instance). In that case, prefer the following:
<?php
function misc_buffered()
{
   
ob_start();
    eval(
$misc);
   
$contents = ob_get_contents();
   
ob_end_clean(); /* <- that's him: it's ob_start() best friend ! */
}
?>

Don't use ob_get_clean() (or any ob_get_* for that matter) for accessing buffered data without  ensuring that either:
  1) You call one of the two available end function afterwise, namely ob_end_clean or ob_end_flush.
  2) You intend to use the output buffer after your function. And you know the consequences. If you don't, please choose (1), it's far easier.

Personal advice: *end* what you *start*. It's like if-endif.

You can find plenty of good advice and documentation on http://fr.php.net/manual/en/ref.outcontrol.php (your mirror / language may vary)
nicolas_rainardNOSPAM at yahoo dot fr
11-Jul-2007 12:56
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).
pierrotevrard at gmail dot com
03-Jul-2007 05:58
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.
udo dot schroeter at gmail dot com
26-May-2007 08:40
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 ;-)
sean at awesomeplay dot com
25-May-2007 11:27
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.
kai dot chan at kaisystems dot co dot uk
16-Mar-2007 12:06
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
f dot boender at electricmonk dot nl
15-Jan-2007 09:39
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).
npugh at tacc dot utah dot edu
18-Nov-2006 03:08
"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).
Slimshady451
09-Nov-2006 03:54
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

?>
samme at vimio
03-Nov-2006 11:06
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.
Joeri
15-Oct-2006 08:07
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 :)
?>
Dale Kern, Salt Lake City
10-Oct-2006 07:16
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.
Nova912
21-Jul-2006 10:17
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.<br>';
            }
        else
            {
            echo
$rq[$survey_number][$i].': Is NULL and IS ok.<br>';
            }
        }
?>

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.
alerante at bellsouth dot net
08-Jul-2006 07:41
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<br>";
} else {
   echo
"eval: total2 is empty<br>";
}

?>

However, this is really a job for "variable variables" < http://php.net/variables.variable >:

<?php

$varname
= "total$i";
if ($
$varname) {
   [...]
}

?>
brettz9 a/- yah00 do/- com
05-Jul-2006 11:19
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"
?>
burninleo at gmx dot net
25-May-2006 02:51
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 ...
}
aoeuid at gmail dot com
14-May-2006 09:50
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.
evildictaitor at hotmail dot com
01-Apr-2006 07:34
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.
aleosha at yandex dot ru
10-Mar-2006 02:43
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).
jnavratil at houston dot rr dot com
25-Feb-2006 12:39
"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).
apmuthu at usa dot net
23-Feb-2006 06:02
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.
nick at hmsonline dot co dot uk
16-Feb-2006 05:22
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]).'");');
}
karig at karig dot net
31-Jan-2006 06:10
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 = "<p>The following is generated by PHP:</p>\n"
    . '<?php $a = 6; $b = 4; $c = $a + $b; '
    . '
echo "<p>Variable c = $c</p>\n"; ?>'
    . "<p>This is just more text.</p>\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 ----

<
p>The following is generated by PHP:</p>
<
p>Variable c = 10</p>
<
p>This is just more text.</p>
jkuckartz1984 at hotmail dot com
29-Jan-2006 01:01
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<br>";
} else {
    echo
"eval: total2 is empty<br>";
}
// returns "empty"
// eval without the ";" will generate a warning

$str="\$refer=&\$total".$i.";";
eval(
$str);
if (
$refer) {
    echo
"eval: total2 is full<br>";
} else {
    echo
"eval: total2 is empty<br>";
}
// returns "full"
?>
Sarangan Thuraisingham
21-Jan-2006 02:47
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.
jurgen at person dot be
18-Dec-2005 06:27
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);
?>
onlyphp
24-Nov-2005 03:59
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 . "\";");
    }
  }
}
matt at mattsoft dot net
10-Sep-2005 07:23
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.
sadi at unicornsoftbd dot com
03-Sep-2005 03:49
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
Nick Johnson - Pixelrific
01-Sep-2005 06:43
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.
TfM
26-Aug-2005 02:06
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 :)
Nick - SafireX
24-Aug-2005 01:26
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();

?>
zcox522 at gmail dot com
17-Aug-2005 09:03
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();
?>
admiral [at] nuclearpixel [dot] com
15-Aug-2005 10:02
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!
jphansen at uga dot edu
08-Aug-2005 09:43
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.
alexandrebr at ignorethis dot gmail dot com
08-Aug-2005 03:32
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><br>";
  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.
the dank
30-Jul-2005 01:26
$foo1 = "the good,<br>";
$foo2 = "the bad,<br>";
$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.
*/
privat at timo-damm dot de
29-Jul-2005 10:03
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
license_to_il
25-Jul-2005 09:44
// 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]