What is the alternative to the eval function?

I am using eval() in my current project as follows:

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

eval() is executed if and only if there is a class called $class_name , so it is safe, but I still don't think this is the best solution.

Can I do what the code above does without eval() ?

+6
source share
5 answers

I recently answered this question . The last part of my answer answers this question perfectly and is much more useful to future readers than the answers here. That is why I answer my question.

PHP has functions that make it possible to avoid using eval in most cases:

  • PHP is a very dynamic language. It has the ability to do the following things with strings :

    • Define and / or get a variable (supported since PHP 4.3). For instance:

       $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

    • Call function (supported by PHP 4.3). For instance:

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

    • Create an instance of the class (PHP 5.0 supported). For instance:

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

      Demo

    • Call a static method (supported by PHP 5.0). For instance:

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

      Demo

      And from PHP 5.3, the class name can also be specified by a string. Example:

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

      Demo

    • The instance method of invoking an instance of an object (PHP 5.0 supported). For instance:

       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

    • Access to object static properties and object instance (supported since PHP 5.0). For instance:

       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

  • PHP has two functions: call_user_func and call_user_func_array for dynamic calls to functions / methods. Both are well documented, so I will not dwell on it here in detail.
  • Even if all of the above is not enough, PHP 5 comes with a great Reflection API . Unfortunately, there are a few examples in the documentation, but thinking is a pretty big topic to cover here. Basically, it's not very important to use reflection after reading how it works.
+11
source

I suggest call_user_func .

An alternative to call_user_func() will call it as follows:

 $class_and_method = 'Class::MyStaticMethod()'; $class_and_method(); 
+6
source

Yes

 call_user_func(array($class_name, 'MyStaticMethod')); 
+5
source

Starting with PHP 5.3+,

 $class_name::MyStaticMethod(); 
+3
source

Adisory: userinput + eval = security hole;

Also, eval is an expensive operation that requires parsing a string in an executable format (a parsing tree, an abstract syntax tree, etc.) and executing a new found logic.

You do not want to analyze every little thing in the code. Use eval if you have something for this to chew on, or rather put this logic somewhere where it is reused and parameterized, for example, a function.

As well as php 5.4

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

Source: https://habr.com/ru/post/916184/


All Articles