3

次のようなDBの列に格納されているメソッド名があります。

customs::nicknames($data)

これは関連するクラスです:

    class customs extends service {

    function __construct() {
        parent::__construct();
    }

    public static function nicknames($data) {
        return $data;
    }

}

このように呼び出すと:

$merge = eval($error['custom'] . ';');

$data 変数の内容は返されません。試してみるとecho、配列を文字列変換phpエラーに正しく返しています。したがって、変数$dataは正しく読み取られます。しかし、なぜ何も返さないのでしょうか?

このように使用せずにこのメソッドを呼び出そうとするとeval():

$merge = customs::nicknames($data);

$dataが正しく返されます。

では、何が問題なのですか?

eval()メソッドの結果を返すことができないのはなぜですか? この問題を解決するにはどうすればよいですか?

4

1 に答える 1

22

eval()がメソッドの結果を返せないのはなぜですか?

eval自分の部分で何も返さないという理由だけで。

ドキュメント:

eval()は、評価されたコードでreturnNULLが呼び出されない限り戻ります。この場合、 returnに渡された値が返されます。


この問題を解決するにはどうすればよいですか?

で変数($merge特定の例では)を割り当てることができますeval。例えば:

eval('$merge =' . $error['custom'] . ';');

またはreturnの値eval。例えば:

$merge = eval('return '.$error['custom'].';');

注:eval実際のアプリケーションでは使用しないでください。

ドキュメントからの警告:

eval()言語構造は、任意の PHP コードを実行できるため、非常に危険です。したがって、その使用はお勧めできません。この構文を使用する以外に選択肢がないことを慎重に確認した場合は、ユーザーが提供したデータを事前に適切に検証せずに渡さないように特に注意してください。


eval()が危険な場合、安全な方法で文字列をコードとして読み取る別の方法はありますか?

はい、あります(実際にはあります):

  1. PHP は非常に動的な言語です。で次のことを行う機能がありますstrings

    • 変数の定義および/または取得 (PHP 4.3 からサポート)。例えば:

      $variableName = 'MyVariable';
      // Create new variable with the name defined in variable $variableName
      ${$variableName} = 'MyValue';
      //Outputs: string(7) "MyValue"
      var_dump($MyVariable);
      //Outputs: string(7) "MyValue"
      var_dump(${'MyVariable'});
      

      デモ

    • 関数の呼び出し (PHP 4.3 からサポート)。例えば:

      // Create function with the name defined in variable $functionName
      function MyFunction($argument) {
          return 'Argument passed is: '.$argument;
      }
      
      $functionName = 'MyFunction';
      
      // Outputs:
      // string(48) "Argument passed is: Calling MyFunction directly."
      var_dump(MyFunction('Calling MyFunction directly.'));
      // Outputs:
      // string(51) "Argument passed is: Calling MyFunction with string."
      var_dump($functionName('Calling MyFunction with string.'));
      

      デモ

    • クラスのインスタンスを作成します (PHP 5.0 以降でサポート)。例えば:

      class MyClass {
          public function __construct() {
              echo 'Constructing MyClass'."\n";
          }
      }
      
      $className = 'MyClass';
      
      $objFromString = new $className();
      // Outputs: object(MyClass)#1 (0) {}
      var_dump($objFromString);
      

      デモ

    • 静的メソッドを呼び出します (PHP 5.0 以降でサポート)。例えば:

      class MyClass {
          public static function staticMethod() {
              return 'MyClass::staticMethod called';
          }
      }
      
      $staticMethodName = 'staticMethod';
      // Outputs: string(28) "MyClass::staticMethod called"
      var_dump(MyClass::$staticMethodName());
      

      デモ

      また、PHP 5.3 からクラス名も文字列で定義できるようになりました。例:

      class MyClass {
          public static function staticMethod() {
          return 'MyClass::staticMethod called';
          }
      }
      
      $className = 'MyClass';
      $staticMethodName = 'staticMethod';
      
      var_dump($className::$staticMethodName());
      var_dump($className::staticMethod());
      

      デモ

    • オブジェクトのインスタンス メソッドを呼び出します (PHP 5.0 からサポート)。例えば:

      class MyClass {
          public function instanceMethod() {
              return 'MyClass::instanceMethod called';
          }
      }
      
      $methodName = 'instanceMethod';
      
      $obj = new MyClass();
      // Outputs: string(30) "MyClass::instanceMethod called"
      var_dump($obj->$methodName());
      

      デモ

    • オブジェクトの静的およびインスタンス プロパティにアクセスします (PHP 5.0 以降でサポート)。例えば:

      class MyClass {
          public static $myStaticProperty;
          public $myInstanceProperty;
      }
      
      $staticPropertyName = 'myStaticProperty';
      $instancePropertyName = 'myInstanceProperty';
      
      MyClass::${$staticPropertyName} = 'my static value';
      $obj = new MyClass();
      $obj->{$instancePropertyName} = 'my instance value';
      
      var_dump(MyClass::${$staticPropertyName});
      var_dump($obj->{$instancePropertyName});
      

      デモ

  2. PHP には 2 つの関数がcall_user_funcありcall_user_func_arrayます。動的関数/メソッド呼び出し用です。どちらも完全に文書化されているので、ここでは詳しく説明しません。
  3. 上記のすべてでは不十分な場合でも、PHP 5 には優れたReflectionAPIが付属しています。残念ながら、ドキュメントには例がほとんどありませんが、リフレクションはここで取り上げる非常に大きなトピックです。基本的に、リフレクションの仕組みを読んだ上でリフレクションを使用することは大したことではありません。
于 2013-07-16T09:02:38.733 に答える