2012-05-20 3 views
6

ich eval() in meinem aktuellen Projekt wie folgt verwenden:Was ist die Alternative der Eval-Funktion?

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

eval(), wenn und nur dann ausgeführt wird, wenn die Klasse mit dem Namen $class_name existiert, so ist es irgendwie sicher, aber ich glaube immer noch nicht, dass dies die beste Lösung ist, .

Kann ich das Gleiche tun, was Code oben ohne eval() tut?

Antwort

11

Ich habe geantwortet kürzlich this question. Der letzte Teil von my answer beantwortet diese Frage perfekt und ist für zukünftige Leser wesentlich nützlicher als die hier gegebenen Antworten. Deshalb beantworte ich meine eigene Frage.

PHP verfügt über Funktionen, die Möglichkeit mit eval in den meisten Fällen zu vermeiden gibt:

  1. PHP sehr dynamische Sprache ist. Es hat die Fähigkeit, mit strings folgenden Dinge zu tun:

    • definieren und/oder erhält Variable (unterstützt von PHP 4.3). Zum Beispiel:

      $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

    • Anruffunktion (unterstützt von PHP 4.3). Zum Beispiel:

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

    • Instanz der Klasse erstellen (unterstützt von PHP 5.0).Zum Beispiel:

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

      Demo

    • Anruf statische Methode (unterstützt von PHP 5.0). Zum Beispiel:

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

      Demo

      Und von PHP 5.3 Klassennamen kann auch durch String definiert werden. Beispiel:

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

      Demo

    • Anrufinstanz Verfahren zur Objekt (unterstützt von PHP 5.0). Zum Beispiel:

      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

    • Zugang statische und Instanzeigenschaften des Objekts (unterstützt von PHP 5.0). Zum Beispiel:

      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 hat zwei Funktionen: call_user_func und call_user_func_array für dynamische Funktion/Methode aufruft. Beide sind perfekt dokumentiert, daher werde ich hier nicht näher darauf eingehen.
  3. Auch wenn alles oben nicht genug ist, kommt PHP 5 mit großen Reflection API. Leider hat die Dokumentation nur wenige Beispiele, aber die Reflexion ist ein ziemlich großes Thema, das hier behandelt werden soll. Grundsätzlich ist es keine große Sache, nach dem Lesen zu lesen, wie es funktioniert.
+2

All diese Informationen (dynamischer Zugriff auf Variablen/Funktionen und Instanzen/statische Mitglieder) sind ziemlich allgemein bekannt und Teil der PHP-Dokumentation. Alles hier als eine Antwort zusammenzufassen, ist nicht besonders nützlich, ohne die Frage selbst zu verändern, von "Was ist die Alternative von eval?" Zu "Was für einen dynamischen Zugang bietet PHP?". –

6

Ich würde vorschlagen call_user_func.

Eine Alternative zu call_user_func() würde es so sein Aufruf:

$class_and_method = 'Class::MyStaticMethod()'; 
$class_and_method(); 
5

ja:

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

Adisory: userinput + eval = Sicherheitslücke;

Auch eval ist eine kostspielige Operation, die das Parsen der Zeichenfolge in ein umsetzbares Format (Syntaxanalysebaum, abstrakte Syntaxstruktur usw.) und das Ausführen der neuen gefundenen Logik erfordert.

Sie möchten nicht jeden kleinen Leckerbissen des Codes überprüfen. Verwenden Sie eval, wenn Sie etwas dafür haben, um zu kauen, oder besser, dass Sie diese Logik irgendwo hinstellen, wo sie wiederverwendet und parametrisiert wird, wie zum Beispiel eine Funktion.

auch als PHP 5,4

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

'eval' erstellt _nicht_ einen neuen Prozess. Beweis: ' scy

+1

Einverstanden, geändert und zurückgezogen. –

3

Ab PHP 5.3+,

$class_name::MyStaticMethod();