Как найти исходный код eval'd функции в PHP? - PullRequest
0 голосов
/ 03 декабря 2008

Я пытаюсь найти способ получить исходный код для (определенных пользователем) функций PHP в строке.

Для нормального кода это легко, используя отражение, я могу найти номер файла и строки, где определена функция; затем я могу открыть файл и прочитать исходный код функции.

Это не будет работать, если функция определена в eval'd-коде. Я не хочу вести учет всего кода eval'd.

Возможно ли это? Если да, то как?

Пример кода:

function myfunction() {
    echo "Test";
}
eval('
  function myevalfunction() {
    echo "Test";
  }
');

$a = new ReflectionFunction('myfunction');
echo $a;

$b = new ReflectionFunction('myevalfunction');
echo $b;

Выход:

Function [ <user> <visibility error> function myfunction ] {
  @@ test.php 3 - 5
}
Function [ <user> <visibility error> function myevalfunction ] {
  @@ test.php(11) : eval()'d code 2 - 4
}

Ответы [ 3 ]

1 голос
/ 03 декабря 2008

Вы не можете просто искать файлы самостоятельно? grep или wingrep идеально подходят для этого.

Если нет, вы можете попробовать функцию pecl rename_function и записать все вызовы eval, которые создают функции.

1 голос
/ 03 декабря 2008

Как насчет того, чтобы определить свою собственную функцию eval и выполнить там отслеживание?

function myeval($code) {
     my_eval_tracking($code, ...);  # use traceback to get more info if necessary
     # (...)
     return eval($code);
}

Тем не менее, я разделяю многие чувства Кента Фредрика по поводу eval в этом случае.

1 голос
/ 03 декабря 2008

Мой первоначальный ответ состоит в том, чтобы сказать, что есть практически 0 веских причин для создания функции в eval.

Вы можете создавать функции условно, то есть:

if ( $cond ){ 
   function foo(){ 

   }
}

Если вы хотите замыкание подобное поведение, я думаю, eval - единственный способ сделать это до PHP5.3, но это EPIC плохой материал, и вы должны избегать всего этого.

Вот почему:

<sub>
<b>01</b> <?php
<b>02</b> 
<b>03</b> function foo ()
<b>04</b> {
<b>05</b>   eval( '
<b>06</b>     function baz()
<b>07</b>     {
<b>08</b>        eval("throw new Exception();"); 
<b>09</b>     }
<b>10</b>   '); 
<b>11</b>   baz(); 
<b>12</b> }
<b>13</b> 
<b>14</b> 
<b>15</b> 
<b>16</b> try{ 
<b>17</b>   foo(); 
<b>18</b> }catch( Exception $e ){
<b>19</b>   var_dump($e); 
<b>20</b> }
<b>21</b> try{ 
<b>22</b>   foo(); 
<b>23</b> }
<b>24</b> catch( Exception $e ){
<b>25</b>   var_dump($e);
<b>26</b> }
</sub>

Который издает это:

<sub>

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
</sub>

Так много зла, так мало усилий.

...