如何在PHP中逐字符串调用(执行)具有类的方法


How to call (execute) Method with class by string in PHP?

示例:

final class A
{
    public static $instance;
    public static function get()
    {
        if (self::$instance === null)
            self::$instance = new self();
        return self::$instance;
    }
    public static function b()
    {
        return array('a','b','c');
    }
}

并且需要通过字符串调用以下方法:

$callString = 'A::get()->b()';

如何通过字符串调用?

你真的尝试过什么吗?就这么简单:

final class A
{
    public static $instance;
    public static function get()
    {
        if (self::$instance === null)
            self::$instance = new self();
        return self::$instance;
    }
    public static function b()
    {
        return array('a','b','c');
    }
}
$class = 'A';//class name
$getter = 'get';//static method
$method = 'b';//public method
$instance = $class::getter();//calls A::get()
$array = $instance->{$method}();//gets array
//check with:
var_dump(
    $class::$getter()
        ->{$method}()
);

如果只有这个字符串(A::get()->b()(可以继续,那么就必须处理/解析这个字符串,并从那里获取它。一个简单但粗糙的方法是通过正则表达式:

$str = 'A::get()->b()';
preg_match_all('/(.+?)(::|'(')-?>?)/', $str, $matches)
{
    $operators = $matches[2];//array('::', '()->', '()')
    $operands = $matches[1];//array('A', 'get', 'b');
    $result = null;
    for ($i=0, $j=count($operands);$i<$j;++$i)
    {
        $result = $operands[$i];//
        switch ($operator[$i])
        {
            case '::':
                $member = $operand[++$i];//next operand
                if (substr($opertator[$i],0,2) === '()')
                    $result = $result::$member();
                else
                    $result = $result::{$member};//static property
                break;
            case '()->'://non-static access
            case '()':
                $result = $result->{$operand[$i]}();
                break;
            default:
                $result = $result->{$operand[$i]};//non-static property
        }
    }
}

请注意,这是未经测试的,边缘非常粗糙,但应该足以让您开始。

这样的东西怎么样?:

$methodName = 'b';
$callString = A::get()->$methodName();