PHP用一个字符串调用多个方法

时间:2012-09-12 14:27:38

标签: php reflection

我有以下字符串:

$str = "methodA()->methodB()->methodC"

我想在对象上称之为“链”

$obj->$str

我目前正在拆分() - >并且一个接一个地呼唤,但必须有更好的方式。

我如何在一条线上调用它?谢谢!

编辑:更多上下文信息:

我为symfony 1.4创建了一个Doctrine Behavior,以便能够从Zend Lucene中搜索到的模式中创建某些表。

简而言之,我需要一种方式来说明行为“要获得可搜索的字段,您必须调用methodA() - > methodB() - > methodC()”

EDIT2: 也许我不够清楚。 $ obj和$ str在运行时确定,因此您的一些建议不适用。

EDIT3: 如果您想知道,我目前正在这样做:

  <?php
  $chain = explode("()->",$str);
  $method = array_shift($chain);
  $value = $obj->$method();
  foreach($chain as $method){
    $value = $value->$method();
  }

6 个答案:

答案 0 :(得分:1)

在我对主要问题发表评论之后,我想到了一个可能的解决方案,虽然有点冗长和手册(你必须制作尽可能多的案例陈述,就像你对链式方法的数量合理预期的那样)。

function chain_execute($obj, $str) {
    $chain = explode("->",$str);
    $chain = array_map('trim', $chain);
    $chain_count = count($chain);
    switch($chain_count) {
        case 1:
            return $obj->{$chain[0]}();
            break;
        case 2:
            return $obj->{$chain[0]}()->{$chain[0]}();
            break;
        case 3:
            return $obj->{$chain[0]}()->{$chain[1]}()->{$chain[2]}();
            break;
        // etc.
        default:
            // not a value you were expecting
            throw new Exception('Invalid number of methods chained: ' . $chain_count);
            break;
    }
}

用法是:

$result = chain_execute($obj, "methodA->methodB->methodC");

答案 1 :(得分:0)

我通常建议不要使用eval,但是......

eval("$obj->$str;");

我会重新评估您的情况,并且可能会按预期逐个调用每个函数。

答案 2 :(得分:0)

你的方法已经很好但是......试试

$str = "{$obj->methodA()->methodB()->methodC()}";

答案 3 :(得分:0)

这是一种邪恶的做法。

你能提供(我很好奇)一个用例吗?

你可以连续使用call_user_func(),你可以编写一个帮助方法,它能够解析你的符号并调用链。

答案 4 :(得分:0)

以下是否有效?

$str = $methodA()->$methodB()->$methodC();

答案 5 :(得分:-1)

我的回答假设您可以访问方法(methodA,methodB和methodC),可以编辑它们,并且每个方法都属于$ obj是其实例的类。

更新每个方法以返回类的实例,假设它们不返回任何原始数据类型(如int,bool,string或其他方式),它将起作用:

<?php
class Example {
    public function methodA() {
        echo "method a\n";
        return $this;
    }
    public function methodB() {
        echo "method b\n";
        return $this;
    }
    public function methodC() {
        echo "method c\n";
        return $this;
    }
}
?>

现在实例化示例,存入$ obj并连续调用您的方法:

<?php
$obj = new Example();
$obj->methodA()->methodB()->methodC();
?>

将输出:

method a
method b
method c