0

我有以下字符串:

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

6 回答 6

2

在写下我对主要问题的评论后,我想到了一个可能的解决方案,虽然有点冗长和手动(你必须做出尽可能多的案例陈述,因为你对链式方法的数量有合理的期望)。

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");
于 2012-09-13T14:36:33.537 回答
0

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

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

不过,我会重新评估您的情况,并且可能会按预期直接一个接一个地调用每个函数。

于 2012-09-12T14:29:08.477 回答
0

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

$str = "{$obj->methodA()->methodB()->methodC()}";
于 2012-09-12T14:30:11.737 回答
0

那是一种邪恶的做法。

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

您可以连续使用call_user_func(),您可以为此编写一个辅助方法,该方法能够解析您的符号并调用链。

于 2012-09-12T14:30:52.930 回答
0

下面的工作吗?

$str = $methodA()->$methodB()->$methodC();
于 2012-09-12T14:39:00.323 回答
0

我的回答假设您可以访问方法(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;
    }
}
?>

现在实例化 Example,存储到 $obj 并连续调用你的方法:

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

这将输出:

method a
method b
method c
于 2012-09-12T19:09:59.847 回答