我有一个自定义PHP类,其中包含很少的方法。可以这样调用类方法:
<?php
class someClass{
function someMethod_somename_1(){
echo 'somename1';
}
function someMethod_somename_2(){
echo 'somename2';
}
}
$obj = new someClass();
$methodName = $_GET['method_name'];
$obj->someMethod_{$methodName}(); //calling method
?>
我的真实世界应用程序更复杂,但在这里我提供了这个简单的例子来获得主要想法。也许我可以在这里使用eval函数?
答案 0 :(得分:4)
请不要使用eval(),因为在大多数情况下它都是 evil 。
简单字符串连接可以帮助您:
$obj->{'someMethod_'.$methodName}();
您还应验证用户输入!
$allowedMethodNames = array('someone_2', 'someone_1');
if (!in_array($methodName, $allowedMethodNames)) {
// ERROR!
}
// Unrestricted access but don't call a non-existing method!
$reflClass = new ReflectionClass($obj);
if (!in_array('someMethod_'.$methodName, $reflClass->getMethods())) {
// ERROR!
}
// You can also do this
$reflClass = new ReflectionClass($obj);
try {
$reflClass->getMethod('someMethod_'.$methodName);
}
catch (ReflectionException $e) {
// ERROR!
}
// You can also do this as others have mentioned
call_user_func(array($obj, 'someMethod_'.$methodName));
答案 1 :(得分:3)
当然,请考虑一下:
$obj = new someClass();
$_GET['method_name'] = "somename_2";
$methodName = "someMethod_" . $_GET['method_name'];
//syntax 1
$obj->$methodName();
//alternatively, syntax 2
call_user_func(array($obj, $methodName));
在调用之前连接整个方法名称。
<强>更新强>
直接调用基于用户输入的方法绝不是一个好主意。考虑先前对方法名称进行一些先验证。
答案 2 :(得分:1)
您也可以利用php魔术方法,即__call()
与call_user_func_array()
和method_exists()
结合使用:
class someClass{
public function __call($method, $args) {
$fullMethod = 'someMethod_' . $method;
$callback = array( $this, $fullMethod);
if( method_exists( $this, $fullMethod)){
return call_user_func_array( $callback, $args);
}
throw new Exception('Wrong method');
}
// ...
}
出于安全考虑,您可能需要创建一个禁止调用其他方法的包装器,如下所示:
class CallWrapper {
protected $_object = null;
public function __construct($object){
$this->_object = $object;
}
public function __call($method, $args) {
$fullMethod = 'someMethod_' . $method;
$callback = array( $this->_object, $fullMethod);
if( method_exists( $this->_object, $fullMethod)){
return call_user_func_array( $callback, $args);
}
throw new Exception('Wrong method');
}
}
并将其用作:
$call = new CallWrapper( $obj);
$call->{$_GET['method_name']}(...);
或者可以创建execute
方法,然后添加到someClass
方法GetCallWrapper()
。
通过这种方式,您可以将功能很好地封装到对象(类)中,并且不必每次都复制它(如果您需要应用某些限制,即特权检查,这可能会派上用场)。
答案 3 :(得分:0)
可以使用变量作为函数。 例如,如果你有函数foo(),你可以有一些变量$ func并调用它。这是一个例子:
function foo() {
echo "foo";
}
$func = 'foo';
$func();
所以它应该像$obj->$func();