7

eval()私は現在のプロジェクトで次のように使用しています。

if (class_exists($class_name)) //$class_name depends on user input
    eval($class_name.'::MyStaticMethod()');

eval()名前のクラスが存在する場合にのみ実行される$class_nameため、安全ですが、これが最善の解決策ではないと思います。

上記のコードなしで同じことを行うことはできますeval()か?

4

5 に答える 5

17

私は最近この質問に答えました。私の答えの最後の部分はこの質問に完全に答えており、ここで提供されている答えよりも将来の読者にとってはるかに役立ちます。だから私は自分の質問に答えています。

evalPHPには、ほとんどの場合に使用を回避する可能性を与える機能があります。

  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. 上記のすべてが十分でない場合でも、PHP5には優れたReflectionAPIが付属しています。残念ながら、ドキュメントにはいくつかの例がありますが、ここで取り上げるのは非常に大きなトピックです。基本的に、それがどのように機能するかを読んだ後にリフレクションを使用することは大したことではありません。
于 2013-07-17T12:42:47.977 に答える
6

私は提案したいと思いますcall_user_func

代わりに、次のcall_user_func()ように呼び出すこともできます。

$class_and_method = 'Class::MyStaticMethod()';
$class_and_method();
于 2012-05-20T07:32:37.433 に答える
5

はい:

call_user_func(array($class_name, 'MyStaticMethod'));
于 2012-05-20T07:33:03.937 に答える
3

PHP 5.3以降では、

$class_name::MyStaticMethod();
于 2012-06-01T01:17:48.850 に答える
1

Adisory:userinput +eval=セキュリティホール;

また、evalは、文字列を実用的な形式(解析ツリー、抽象構文ツリーなど)に解析し、新しく見つかったロジックを実行する必要がある高価な操作です。

ちょっとしたコードをすべて評価したくはありません。噛み砕くための何かがある場合はevalを使用するか、関数などの再利用可能でパラメーター化された場所にそのロジックを配置します。

また、php5.4以降

$method = array('class_name', 'method_name');
$method(); // calls class_name::method_name()
于 2012-05-20T08:48:36.443 に答える