0

(ユーザー定義の) PHP 関数のソース コードを文字列で取得する方法を見つけようとしています。

通常のコードの場合、これは簡単です。リフレクションを使用すると、関数が定義されているファイルと行番号を見つけることができます。次に、ファイルを開いて関数のソース コードを読むことができます。

関数が評価されたコードで定義されている場合、これは機能しません。すべての評価済みコードを記録したくありません。

これは可能ですか?はいの場合、どのように?

コード例:

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
}
4

4 に答える 4

1

自分でファイルを検索することはできませんか? grep または wingrep はこれに最適です。

そうでない場合は、pecl 関数 rename_function を試して、関数を作成するすべての eval 呼び出しをログに記録できます。

于 2008-12-03T16:07:48.460 に答える
1

独自の eval-function を定義して、そこで追跡を行ってみませんか?

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

そうは言っても、この場合の eval に対する Kent Fredric の気持ちはよくわかります。

于 2008-12-03T16:40:34.650 に答える
1

私の最初の反応は、eval で関数を作成する正当な理由は事実上ゼロであるということです。

条件付きで関数を作成できます。つまり、次のようになります。

if ( $cond ){ 
   function foo(){ 

   }
}

クロージャーのような動作が必要な場合は、eval が PHP5.3 まではそれを行う唯一の方法だと思いますが、そのEPICの悪い点とすべてのコストを回避する必要があります。

理由は次のとおりです。


01 <?php
 02  
03 function foo ()
 04 {
 05    eval( '
 06      function baz()
 07      {
 08         eval("throw new Exception();"); 
 09      }
 10    '); 
11   バズ(); 
12 }
 13  
14  
15  
16試してください{ 
 17    foo(); 
18 }catch( Exception $e ){
 19    var_dump($e); 
20 }
 21トライ{ 
 22    foo(); 
23 }
 24catch( 例外 $e ){
 25    var_dump($e);
26 }

これを発行するもの:



オブジェクト(例外)#1 (6) {
  ["メッセージ:保護"]=>
  文字列(0) ""
  ["string:private"]=>
  文字列(0) ""
  ["コード:保護"]=>
  int(0)
  ["ファイル:保護"]=>
  string(50) "/tmp/xx.php(10) : eval() したコード (4) : eval() したコード"
  ["回線:保護"]=>
  int(1)
  ["トレース:プライベート"]=>
  配列(3) {
    [0]=>
    配列(3) {
      ["ファイル"]=>
      string(31) "/tmp/xx.php(10) : eval() したコード"
      ["線"]=>
      int(4)
      ["関数"]=>
      文字列(4)「評価」
    }
    [1]=>
    配列(4) {
      ["ファイル"]=>
      文字列(11) "/tmp/xx.php"
      ["線"]=>
      int(11)
      ["関数"]=>
      文字列(3) "バズ"
      ["引数"]=>
      配列(0) {
      }
    }
    [2]=>
    配列(4) {
      ["ファイル"]=>
      文字列(11) "/tmp/xx.php"
      ["線"]=>
      int(17)
      ["関数"]=>
      文字列(3)「フー」
      ["引数"]=>
      配列(0) {
      }
    }
  }
}

致命的なエラー: baz() (以前に /tmp/xx.php(10) で宣言された: eval() されたコード:2) を /tmp/xx.php(10) で再宣言できません: 行の eval() されたコード5

コール スタック:
    0.0002 115672 1. {メイン}() /tmp/xx.php:0
    0.0006 122304 2. foo() /tmp/xx.php:22

非常に多くの悪、非常に少ない努力。

于 2008-12-03T16:01:26.930 に答える