我使用eval()
在我目前喜欢这个项目:
if (class_exists($class_name)) //$class_name depends on user input
eval($class_name.'::MyStaticMethod()');
eval()
被执行,当且仅当与类名$class_name
存在,所以它还挺安全的,但我仍然不认为这是最好的解决办法。
我可以做同样的东西上面的代码没有做eval()
我使用eval()
在我目前喜欢这个项目:
if (class_exists($class_name)) //$class_name depends on user input
eval($class_name.'::MyStaticMethod()');
eval()
被执行,当且仅当与类名$class_name
存在,所以它还挺安全的,但我仍然不认为这是最好的解决办法。
我可以做同样的东西上面的代码没有做eval()
我最近回答了这个问题 。 最后一部分我的答案完全回答这个问题,是不是在这里提供的答案未来的读者有用得多。 这就是为什么我回答我的问题。
PHP具有的功能,使可能避免使用eval
在大多数情况下:
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'});
演示
通话功能(从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.'));
演示
创建类的实例(从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);
演示
调用静态方法(从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());
演示
而从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());
演示
对象的呼叫实例方法(从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());
演示
对象的访问静态和实例属性(从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});
演示
call_user_func
和call_user_func_array
动态函数/方法调用。 这两个是完全记录,所以我不会在细节去这里。 Reflection
API 。 不幸的是,文档有几个例子,但反射是相当大的话题在这里介绍。 基本上,这不是什么大不了的阅读它的工作原理后,使用反射。 我建议call_user_func
。
以另一种call_user_func()
将调用它是这样的:
$class_and_method = 'Class::MyStaticMethod()';
$class_and_method();
是:
call_user_func(array($class_name, 'MyStaticMethod'));
由于PHP 5.3+的,
$class_name::MyStaticMethod();
Adisory:userinput + EVAL =安全漏洞;
也EVAL是昂贵的操作,要求解析串入一个可操作的格式(解析树,抽象语法树等),并执行该新发现的逻辑。
你不想给eval代码的每一小珍闻。 如果你有什么让它啃或者说把这个逻辑的地方在那里它的可重复使用和参数化等功能使用eval。
另外,作为PHP 5.4的
$method = array('class_name', 'method_name');
$method(); // calls class_name::method_name()