Reputation: 26862
I am 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 function source code.
This will not work if a function is defined in eval'd code. I do not want to keep record of all eval'd code.
Is this possible? If yes, then how?
Example 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
}
Upvotes: 0
Views: 3511
Reputation: 1285
If you want to find the source code, even in a debugger, you can define your own eval() function which works with temporary files:
function my_eval($code) {
$file = << TEMP-DIR >> . '/' . md5($code) . '.php';
if (!file_exists($file)) {
file_put_contents($file, "<?php\n" . $code);
}
return require($file);
}
In fact, I think that if you call this function eval
and put it in the default namespace, most eval() calls in the code will call this function instead.
Upvotes: 1
Reputation: 1078
How about 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);
}
That said, I do share a lot of Kent Fredric's feelings on eval in this case.
Upvotes: 1
Reputation: 57374
My initial response is to say there's virtually 0 good reason to create a function in eval.
You can create functions conditionally, ie:
if ( $cond ){
function foo(){
}
}
If you want closure like behaviour I guess eval is the only way to do it until PHP5.3, but its EPIC bad stuff and you should avoid it all cost.
Here is 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 } 24 catch( Exception $e ){ 25 var_dump($e); 26 }
Which Emits 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 5 Call Stack: 0.0002 115672 1. {main}() /tmp/xx.php:0 0.0006 122304 2. foo() /tmp/xx.php:22
So much badness, so little effort.
Upvotes: 1
Reputation: 10033
You cant just search through the files yourself? grep or wingrep is perfect for this.
If not you can try the pecl function rename_function and log all the eval calls which create functions.
Upvotes: 1