2012-05-20 15 views
6

私はこのように私の現在のプロジェクトでeval()を使用しますと、それはちょっと安全ですので、名前$class_nameを持つクラスが存在する場合だけeval関数の代替手段は何ですか?

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

eval()が実行されますが、私はまだ、これが最善の解決策であるとは思いません。

eval()を使用せずに上記のコードを実行できますか?

答えて

11

私は最近this questionに答えています。 my answerの最後の部分は完全にこの質問に答えており、将来の読者にとってはここで提供される回答よりもはるかに有用です。だから私は自分の質問に答えている。

  1. PHPは非常に動的な言語です:

    PHPはほとんどの場合、evalを使用しないように可能性を与える機能を備えています。それは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'}); 
      

      Demo

    • コール機能(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.')); 
      

      Demo

    • (PHP 5.0からサポートされている)クラスのインスタンスを作成します。例えば:(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); 
      

      Demo

    • コール静的方法。たとえば:

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

      Demo

      そして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()); 
      

      Demo

    • コールインスタンス(PHP 5.0からサポートされている)オブジェクトのメソッド。例えば:(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()); 
      

      Demo

    • アクセス静的およびインスタンスのプロパティ。たとえば、次の動的関数/メソッド呼び出しのcall_user_funccall_user_func_array

      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}); 
      

      Demo

  2. PHPは2つの機能を有しています。両方とも完全に文書化されているので、私はここでは詳しく説明しません。
  3. 上記のすべてが十分でない場合でも、PHP 5には素晴らしいReflection APIが付いています。残念ながら、ドキュメンテーションにはいくつかの例がありますが、ここでは反射はかなり大きなトピックです。基本的には、それがどのように動作するかを読んだ後でリフレクションを使うのは大したことではありません。
+2

これらの情報(変数/関数とインスタンス/静的メンバーへの動的アクセス)は、よく知られており、PHPドキュメントの一部です。これをすべて答えとして集約することは、質問自体を「evalの代替手段」から「PHPが提供する動的アクセス」に変えなければ、特に有用ではありません。 –

5

はい:

call_user_func(array($class_name, 'MyStaticMethod')); 
0

Adisory:

call_user_func()の代わりに、このようにそれを呼び出すことになる ユーザ入力+のeval =セキュリティホール。

また、evalは、文字列を実行可能な形式(構文木、抽象構文木など)に解析し、新しい発見された論理を実行する高価な操作です。

あなたは少しずつ小さなコードを評価したくありません。あなたが噛んでいるか、あるいは関数のように再利用可能でパラメータ化されているどこかにそのロジックを置きたい場合は、evalを使用してください。 PHP PHP 5.3+のよう5.4

$method = array('class_name', 'method_name'); 
$method(); // calls class_name::method_name() 
+0

'eval'は新しいプロセスを作成しません。証明: '<?php echo getmypid()。 "\ n"; eval( 'echo getmypid()。\\ n ";'); ' – scy

+1

同意、修正、取り消し。 –

3

のようにも

$class_name::MyStaticMethod(); 
関連する問題