views:

163

answers:

5

I was wondering if PHP can do this as there seems to be no good solution to it yet:

p($i)

and it will print

$i is 5

and

p(1 + 2)

will print

1 + 2 is 3

and

p($i * 2)  =>  $i * 2 is 10  
p(3 * factorial(3))  =>  3 * factorial(3) is 18

C and Ruby both can do it... in C, it can be done by stringification, and in Ruby, there is a solution using p{'i'} or p{'1 + 2'} (by passing the block with the binding over, to do an eval)... I wonder in PHP, is it possible too?

A: 

Well, if you pass in a string, you can use eval to do the calculation.

Pesto
the function won't be able to evaluate the global though
動靜能量
A: 

I don't believe so, but this might be a good substitute:

$myFunction = '1+2';
echo $myFunction;
echo eval( $myFunction );
Christopher W. Allen-Poole
+3  A: 

I think it could be done by taking a backtrace then loading and tokenizing the file that calls p(). I wouldn't call it a "good" solution though.

Of course you could stringify it yourself...

p('$i');

function p($str) 
{
    echo $str, " = ", eval("return ($str);");
}
Greg
Using `var_export` would be nice.
Gumbo
stingify it myself... that's so funny
動靜能量
+2  A: 

If you mess with the string to make it into a return statement, you can use eval...

function p($expr)
{
   $php="return {$expr};";
   echo "$expr is ".eval($php)."\n";
}


p("1+2");

Works for simple expressions, but if you tried to reference a variable in your $expr, then it wont find it inside the scope of function p() - a little hack like the following can help:

function p($expr)
{
   $php="return {$expr};";
   $php=preg_replace('/\\$(\w+)/', '$GLOBALS[\'$1\']', $php);


   echo "$expr is ".eval($php)."\n";
}

$x=5;
p('$x+4');

Here we've search for variable references in the code and turned them into $GLOBALS array references. The expression $x+4 is turned into return $GLOBALS['x']+4;

Not sure I'd ever want to see this in production code though :)

Paul Dixon
A: 

Short answer: no

The problem with eval() based solutions is scope. The following won't work:

function p($expr)
{
   $php="return {$expr};";
   echo "$expr is ".eval($php)."\n";
}

$i = 10;

p('$i + 1');

because $i won't be in scope when eval() is called.

D. Evans