0

Example:

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

And Need to call the following method by string:

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

How to call this via string?

4
  • 1
    eval(), but you are doing it seriously wrong if you need to do what you want. Why do you need to call that string? Commented Jul 14, 2014 at 9:57
  • You want the whole line to be passed in as string? Awfully drastic but t use eval Commented Jul 14, 2014 at 9:59
  • @PeeHaa jinx! You owe me a coke! Commented Jul 14, 2014 at 10:00
  • @Anthony No point in using eval, assign string parts to variables, and construct your statement using those variables Commented Jul 14, 2014 at 10:02

2 Answers 2

1

Have you actually tried something? It's as simple as this:

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

If you only have this string (A::get()->b()) to go on, you'll have to process/parse that string, and take it from there. A simple, but crude way to do so would be through regex:

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

Note that this is un-tested, and very rough around the edges, but it should be enough to get you started.

Sign up to request clarification or add additional context in comments.

Comments

0

How about something like that?:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.