eval函数的替代方案是什么?

Ler*_*eri 7 php eval

eval()在我当前的项目中使用如下:

if (class_exists($class_name)) //$class_name depends on user input
    eval($class_name.'::MyStaticMethod()');
Run Code Online (Sandbox Code Playgroud)

eval()当且仅当具有该名称的类$class_name存在时才执行,因此它有点安全,但我仍然认为这不是最佳解决方案.

我可以做同样的代码eval()吗?

Ler*_*eri 14

我最近回答了这个问题.我的答案的最后一部分完美地回答了这个问题,对于未来的读者来说,这里提供的答案远比这里提供的答 这就是我回答自己问题的原因.

PHP具有eval在大多数情况下可以避免使用的功能:

  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'});
      
      Run Code Online (Sandbox Code Playgroud)

      演示

    • 调用函数(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.'));
      
      Run Code Online (Sandbox Code Playgroud)

      演示

    • 创建类的实例(从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);
      
      Run Code Online (Sandbox Code Playgroud)

      演示

    • 调用静态方法(从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());
      
      Run Code Online (Sandbox Code Playgroud)

      演示

      而从PHP 5.3类名也可以用string定义.例:

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

      演示

    • 调用对象的实例方法(从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());
      
      Run Code Online (Sandbox Code Playgroud)

      演示

    • 访问对象的静态和实例属性(从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});
      
      Run Code Online (Sandbox Code Playgroud)

      演示

  2. PHP有两个功能:call_user_funccall_user_func_array动态功能/方法调用.两者都有完整的记录,所以我不会在这里详细介绍.
  3. 即使上面的所有内容都不够,PHP 5也提供了出色的ReflectionAPI.遗憾的是,文档中的示例很少,但反思是一个非常大的主题.基本上,在阅读它的工作原理后使用反射并不是什么大问题.

  • 所有这些信息(动态访问变量/函数和实例/静态成员)都是非常常见的知识,也是PHP文档的一部分.如果不将问题本身从"eval的替代方案"更改为"PHP提供的动态访问",那么将其全部聚合在一起作为答案并不是特别有用. (2认同)

pdu*_*ler 6

我建议call_user_func.

另一种方法是call_user_func()将其称为:

$class_and_method = 'Class::MyStaticMethod()';
$class_and_method();
Run Code Online (Sandbox Code Playgroud)


dev*_*ler 5

是:

call_user_func(array($class_name, 'MyStaticMethod'));
Run Code Online (Sandbox Code Playgroud)