7 Stimmen

Was ist die Alternative zur eval-Funktion?

Ich verwende eval() in meinem aktuellen Projekt so:

if (class_exists($class_name)) //$class_name hängt von Benutzereingaben ab
    eval($class_name.'::MyStaticMethod()');

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

Kann ich das Gleiche wie der obige Code ohne eval() machen?

18voto

Leri Punkte 12217

Ich habe kürzlich diese Frage beantwortet. Der letzte Teil meiner Antwort beantwortet diese Frage perfekt und ist für zukünftige Leser viel nützlicher als die hier zur Verfügung gestellten Antworten. Deshalb beantworte ich meine eigene Frage.

PHP bietet Funktionen, die es in den meisten Fällen ermöglichen, auf die Verwendung von eval zu verzichten:

  1. PHP ist eine sehr dynamische Sprache. Es hat die Fähigkeit, folgende Dinge mit Strings zu tun:

    • Variable definieren und/oder abrufen (unterstützt ab PHP 4.3). Zum Beispiel:

      $variableName = 'MyVariable';
      // Neue Variable mit dem im Variablen $variableName definierten Namen erstellen
      ${$variableName} = 'MyValue';
      //Ausgabe: string(7) "MyValue"
      var_dump($MyVariable);
      //Ausgabe: string(7) "MyValue"
      var_dump(${'MyVariable'});

      Demo

    • Funktion aufrufen (unterstützt ab PHP 4.3). Zum Beispiel:

      // Funktion mit dem im Variablen $functionName definierten Namen erstellen
      function MyFunction($argument) {
          return 'Der übergebene Argument ist: '.$argument;
      }
      
      $functionName = 'MyFunction';
      
      // Ausgaben:
      // string(48) "Der übergebene Argument ist: Direkt MyFunction aufrufen."
      var_dump(MyFunction('Direkt MyFunction aufrufen.'));
      // Ausgaben:
      // string(51) "Der übergegebene Argument ist: MyFunction-String aufrufen."
      var_dump($functionName('MyFunction-String aufrufen.'));

      Demo

    • Instanz einer Klasse erstellen (unterstützt ab PHP 5.0). Zum Beispiel:

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

      Demo

    • Statische Methode aufrufen (unterstützt ab PHP 5.0). Zum Beispiel:

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

      Demo

      Und seit PHP 5.3 kann der Klassenname auch als String definiert werden. Beispiel:

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

      Demo

    • Instanzmethode eines Objekts aufrufen (unterstützt ab PHP 5.0). Zum Beispiel:

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

      Demo

    • Statische und Instanzvariablen eines Objekts abrufen (unterstützt ab PHP 5.0). Zum Beispiel:

      class MyClass {
          public static $myStaticProperty;
          public $myInstanceProperty;
      }
      
      $staticPropertyName = 'myStaticProperty';
      $instancePropertyName = 'myInstanceProperty';
      
      MyClass::${$staticPropertyName} = 'mein statischer Wert';
      $obj = new MyClass();
      $obj->{$instancePropertyName} = 'mein Instanzwert';
      
      var_dump(MyClass::${$staticPropertyName});
      var_dump($obj->{$instancePropertyName});

      Demo

  2. PHP bietet zwei Funktionen: call_user_func und call_user_func_array für dynamische Funktions-/Methodenaufrufe. Beide sind perfekt dokumentiert, daher gehe ich hier nicht ins Detail.

  3. Selbst wenn alles oben Genannte nicht ausreicht, bietet PHP 5 das großartige Reflection API. Leider gibt es nur wenige Beispiele in der Dokumentation, aber die Reflektion ist ein recht großes Thema, um es hier abzudecken. Im Grunde ist es kein Problem, die Reflektion nach dem Verständnis, wie sie funktioniert, zu verwenden.

6voto

pdu Punkte 10069

Ich würde call_user_func vorschlagen.

Ein Alternativ zu call_user_func() wäre es, es so aufzurufen:

$klasse_und_methode = 'Klasse::MeineStatischeMethode()';
$klasse_und_methode();

5voto

dev-null-dweller Punkte 28932

Ja:

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

3voto

newacct Punkte 114757

Ab PHP 5.3+

$class_name::MyStaticMethod();

1voto

Mihai Stancu Punkte 15260

Advisory: userinput + eval = Sicherheitslücke;

Außerdem ist eval eine teure Operation, die die Zeichenfolge in ein ausführbares Format (Parsenbaum, abstrakter Syntaxbaum usw.) umwandeln und die neu gefundene Logik ausführen muss.

Sie möchten nicht jede kleine Code-Schnipsel mit eval auswerten. Verwenden Sie eval, wenn Sie etwas haben, worauf es ankommt, oder platzieren Sie diese Logik lieber an einem Ort, an dem sie wiederverwendbar und parametrisiert ist, wie z. B. in einer Funktion.

Auch ab php 5.4

$method = array('Klassenname', 'Methodenname');
$method(); // ruft Klassenname::Methodenname() auf

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X