1

我有一个自定义 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 函数?

4

4 回答 4

4

请不要使用eval()因为它在大多数情况下都是邪恶的。

简单的字符串连接可以帮助您:

$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));
于 2012-11-11T22:00:55.540 回答
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));

在调用之前连接整个方法名称。

更新:

根据用户输入直接调用方法绝不是一个好主意。考虑之前对方法名称进行一些验证。

于 2012-11-11T22:01:01.127 回答
1

您还可以利用 php 魔术方法,即__call()call_user_func_array()and结合使用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()

这样您就可以将功能很好地封装到对象(类)中,并且不必每次都复制它(如果您需要应用一些限制,例如权限检查,这可能会派上用场)。

于 2012-11-11T22:02:14.673 回答
0

可以将变量用作函数。例如,如果你有函数 foo() 你可以有一些变量 $func 并调用它。这是示例:

function foo() {
    echo "foo";
}

$func = 'foo';
$func();  

所以它应该像$obj->$func();

于 2012-11-11T22:05:58.313 回答