如何在PHP中按字符串调用(执行)方法?

时间:2014-07-14 09:54:18

标签: php callback

示例:

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()';

如何通过字符串调用此方法?

2 个答案:

答案 0 :(得分:1)

你真的尝试过一些东西吗?它很简单:

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
        }
    }
}

请注意,这是未经测试的,并且边缘非常粗糙,但它应该足以让您入门。

答案 1 :(得分:0)

这样的事情怎么样?:

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