How do I find the source code for the eval'd function in PHP?
I'm trying to find a way to get the source code for (user-defined) PHP functions in a string.
For normal code this is easy, using reflection I can find the file and line numbers where the function is defined; then I can open the file and read the source code of the function.
This will not work if the function is defined in the eval'd code. I don't want to write all the eval'd code.
Is it possible? If so, how?
Sample code:
function myfunction() {
echo "Test";
}
eval('
function myevalfunction() {
echo "Test";
}
');
$a = new ReflectionFunction('myfunction');
echo $a;
$b = new ReflectionFunction('myevalfunction');
echo $b;
Output:
Function [ <user> <visibility error> function myfunction ] {
@@ test.php 3 - 5
}
Function [ <user> <visibility error> function myevalfunction ] {
@@ test.php(11) : eval()'d code 2 - 4
}
source to share
How about how you define your own eval function and do the tracking there?
function myeval($code) {
my_eval_tracking($code, ...); # use traceback to get more info if necessary
# (...)
return eval($code);
}
However, I do share a lot of Kent Fredrick's feelings on eval in this case.
source to share
My initial answer is to say that there is actually a 0 good reason for creating a function in eval.
You can create functions conditionally, that is:
if ( $cond ){
function foo(){
}
}
If you need closure -like behavior, I think eval is the only way to do it before PHP5.3, but its bad EPIC stuff and you should avoid its cost.
That's why:
01 ? <Php 02 03 function foo () 04 { 05 eval ( ' 06 function baz () 07 { 08 eval ( "throw new Exception () ;"); 09 } 10 '); 11 baz (); 12 } 13 14 15 16 try { 17 foo (); 18 } catch (Exception $ e) { 19 var_dump ($ e); 20 } 21 try { 22 foo (); 23 } 24catch (Exception $ e) { 25 var_dump ($ e); 26 }
What publishes this:
object (Exception) # 1 (6) { ["message: protected"] => string (0) "" ["string: private"] => string (0) "" ["code: protected"] => int (0) ["file: protected"] => string (50) "/tmp/xx.php(10): eval () 'd code (4): eval ()' d code" ["line: protected"] => int (1) ["trace: private"] => array (3) { [0] => array (3) { ["file"] => string (31) "/tmp/xx.php(10): eval () 'd code" ["line"] => int (4) ["function"] => string (4) "eval" } [1] => array (4) { ["file"] => string (11) "/tmp/xx.php" ["line"] => int (11) ["function"] => string (3) "baz" ["args"] => array (0) { } } [2] => array (4) { ["file"] => string (11) "/tmp/xx.php" ["line"] => int (17) ["function"] => string (3) "foo" ["args"] => array (0) { } } } } Fatal error: Cannot redeclare baz () (previously declared in /tmp/xx.php(10): eval () 'd code: 2) in /tmp/xx.php(10): eval ()' d code on line five Call Stack: 0.0002 115672 1. {main} () /tmp/xx.php 0 0.0006 122304 2.foo () /tmp/xx.php:22
So much bad, so little effort.
source to share