PHP5中的链接方法


Chaining methods in PHP5

好了,伙计们。这是我一直在思考的一件事:

因为在PHP5中可以将方法链接起来,我想知道是否有可能通过一种智能的方式进一步确定方法是否在链中最后执行-并且不使用名为getResult()的第三个方法?

普通方法调用:

$myClass->dofirst(); // Data is returned from the dofirst-method

我想要什么;

$myclass->dofirst()->sortOutputfromDofirstAndReturn();

这个想法是第二个方法,sortOutputfromDofirstAndReturn()将阻止dofirst()方法返回,而是执行第二个方法中声明的逻辑,而不需要第三个方法将返回结果反弹给用户。

可能有点混乱,所以如果我需要澄清什么,请告诉我!

如果我正确理解问题,那么这将工作。我一直称它为流体界面,但我不知道这个名字是否正确。从本质上讲,它的工作原理是在每个方法的末尾返回this,如下面的例子所示。

class Foo {
    public function doFirst() {
        $this->bar = array('b', 'c', 'a');
        return $this;
    }
    public function sortOutputfromDofirstAndReturn() {
        sort($this->bar);
        return $this;
    }
}

方法调用是顺序执行的,您必须返回一个对象,以便您可以在其上调用方法。如果dofirst()返回普通数据,这是不可能的。

我认为这是唯一可能的,如果数据是字符串,使用魔术方法

class MyClass{
  public function __toString(){
    return $this->data;
  }
  public function dofirst(){
    $this->data='Hello';
    return $this;
  }
  public function sort(){
    $this->data.=' World';
    return $this;
  }    
}
$obj = new MyClass;
echo $obj->dofirst(); //Hello
echo $obj->dofirst()->sort(); //Hello world

有几种可能性:

添加一个(或几个特殊的)方法(见文档1.2)完成链(execute是特殊的)

$q = new Doctrine_Query();
$q->select('Foo')->where('bar = 1')->orderBy('bar')->execute();

如果最终结果总是像数组一样的对象,那么你可以用你的链逻辑实现Iterator接口。

class Chain implements Iterator { /* implementation */ }
$c = new Chain();
foreach ($c->first()->second() as $item) { /* do stuff */ }

一半愚蠢的人。如果你的结果是字符串,那么重新实现__toString方法…

doFirst() 必须返回一些东西(特别是一个对象)才能符合链接条件。sortOutputfromDofirstAndReturn()将对doFirst()返回的对象进行操作,因此doFirst()应该这样返回:

public function doFirst() {
     // snip
     return $this;
}
因此,最后一个方法(本例中为sortOutputfromDofirstAndReturn())不能也不应该阻止链中较早的方法返回。但是,要确保这些早期方法返回一个对象(而不是输出或其他数据),这取决于开发人员。

我不是100%确定你在问什么;如果你想让第二个"sort"函数处理doFirst的输出,为什么不直接使用

呢?

$myclass->sortOutputfromDofirstAndReturn(dofirst());

和doFirst()返回的东西吗?正如其他人所说,doFirst必须返回$this或对象才能正常工作。如果我没看错的话你只是想用方法2来操作方法1应该返回的东西

你基本上是在问你是否可以链式方法,其中前一个传递它的数据到下一个没有"返回"。假设你只在对象上链接方法,并且不捕获任何返回值,但最后一个方法调用(如果你链接应该只是返回另一个引用到你已经拥有的对象),它已经这样做了。如果dofirst()返回一些从未被看到的值,这真的无关紧要。此处没有发现任何性能增强。

编辑

我想我误解了你的问题,因为你说你理解方法链。你问的只是返回它们所属对象的函数。当您调用$myclass->dofirst()时,您只是从$myclass对象调用dofirst函数。如果你想把一个方法链接到this,你需要dofirst再次返回这个对象,以便在它上面调用另一个函数。

class MyClass{
    function dofirst()
    {
        // do something
        return $this; // return the object you were calling this function on
    }
}

如果你现在看看代码是如何执行的,$myclass->dofirst()将返回对$myclass的引用,然后你可以在链中调用sortOutputfromDofirstAndReturn(): $myclass->dofirst()->sortOutputfromDofirstAndReturn(); .

看一下工厂模式,看看方法链被大量使用的例子。