我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
AP I。不幸的是,文档中的示例很少,但反射是这里要讨论的一个很大的话题。基本上,在阅读了它的工作原理之后使用反射并不是什么大不了的事。我建议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。
同样从 php 5.4 开始
$method = array('class_name', 'method_name');
$method(); // calls class_name::method_name()