通过字符串调用方法?

62
Class MyClass{
  private $data=array('action'=>'insert');
  public function insert(){
    echo 'called insert';
  }

  public function run(){
    $this->$this->data['action']();
  }
}

这个无效:

$this->$this->data['action']();

是否只有使用call_user_func()的可能性?

2个回答

137

尝试:

$this->{$this->data['action']}();

一定要检查操作是否被允许并且可以被调用


<?php

$action = 'myAction';

// Always use an allow-list approach to check for validity
$allowedActions = [
    'myAction',
    'otherAction',
];

if (!in_array($action, $allowedActions, true)) {
    throw new Exception('Action is not allowed');
}

if (!is_callable([$this, $action])) {
    // Throw an exception or call some other action, e.g. $this->default()
    throw new Exception('Action is not callable');
}

// At this point we know it's an allowed action, and it is callable
$this->$action();


4
一定要先检查函数是否存在:function_exists()! - Jesse Bunch
它可以工作。我应该使用任何安全技巧,比如函数存在或函数允许数组吗? - Marek Bar
3
如果输入来自用户,您应该始终恰当地对其进行转义。最好使用允许操作的白名单。 - Mārtiņš Briedis
@JesseBunch,如果你已经使用了is_callable进行检查,就不需要再使用function_exist。 - gagarine
1
值得一提的是,在某些版本的PHP中,is_callable函数不尊重可见性,正如文档中所评论的那样。 - xDaizu

17

再强调一下原帖所提到的,call_user_func()call_user_func_array() 也是不错的选择。特别是在参数列表可能因每个函数而异时,call_user_func_array() 在传递参数方面做得更好。

call_user_func_array(
    array($this, $this->data['action']),
    $params
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接