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