2

I was been doing a php testing which uses eval() function, but it seems that eval() can't call user defined functions properly.

Please see my example:

function equals($a,$b){  
        if ($t == $r){  
        return true;  
        }  
    else{  
                throw new Exception("expected:<".$r."> but was:<".$t.">");  
    }  
}
eval("$test = 1;");  
try{  
    echo eval("equals($test,1);");  
}  
catch (Exception $e) {  
    echo $e->getMessage();  
}  

but what I have received is always like "expected:<1> but was:<>", but if I have do an

echo $test;

I can get 1.

I have tried changing $ to \$ by following the PHP eval() Manual, but it seems to break the eval function. (http://php.net/manual/en/function.eval.php)

So I am a bit of stack now, can someone help me with the problem. Thank you very much.

2
  • Code should have lines prefixed with four spaces (hint: Ctrl+K), not right angle brackets. Commented Mar 2, 2011 at 13:16
  • I will go back and try first. Thx guys. Commented Mar 3, 2011 at 0:58

3 Answers 3

6

Don't use eval().

If you want to call a user-defined function, say, derp, with the name at runtime:

$functionName = 'derp';
$functionName(argument1, argument2, ...);

Notice how I prefixed functionName with $ so I'm not calling functionName but rather, derp.

So, for your example, calling a user-defined function, equals:

$functionName = 'equals';
$functionName($test, 1);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for suggestion, but the problem is that I am get string as code, so it's hard to use it in this way, as I need to do a regex to get the function name and arguments.
Very useful, I didn't know about this. I though eval was my only solution, now 'eval' is 'evil' again. :)
5

you are missing return

echo eval("return equals(\"$test\",1);");

From PHP manual

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.

eval()

avoid to use eval() as @Delan suggested.

Comments

0

If you want to use eval, I believe the problem is that you need to escape both $ (it wasn't clear from your post if you did that). So your code would read

    function equals($a,$b){           
if ($t == $r){          
 return true;           
}      
 else
{                   
throw new Exception("expected:<".$r."> but was:<".$t.">");       
}  
 } 
eval("\$test = 1;");   
try{       
echo eval("equals(\$test,1);");   
}   
catch (Exception $e) {      
 echo $e->getMessage();  
 }  

You could also use single quotes for your eval strings which do not evaluate variables. As others have pointed out, though, there may be better ways of doing this.

7 Comments

Well, the only difference avoiding $test interpolation would be if the string was made not at the same time as eval() is called with it. In that case, $test will be evaluated during eval() and not when the string is created.
Good point I didn't try leaving off the second eval. The first eval fails when I run it without the \$ in my test because you are evaling " = 1;" which is syntactically incorrect.
@david PHP 5, yeah, for first eval can past, but maybe because that $test is coming from eval function, the second one is not running, but don't know how to fix it. :(
@Delan Azabani thx, I just use $test as an example, in actual work is not $test.
@david error like : com.caucho.quercus.parser.QuercusParseException: string::1: unknown lexeme:\ instring::0: equals(\$a,1); I forget to mention that it is in quercus, but I think it quite similar to PHP. Besides that I have tried eval("equals(2,1);"), it works.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.