流体接口如何同时返回$this和一个值


How does a fluid interface return both $this and a value?

我对OOP比较陌生,所以浏览了简单HTML DOM的文档,我想知道它的方法是如何使用方法链接和返回值/对象的常规行为的。

例如:

 $html = new simple_html_dom();
 $html -> find('something'); // Returns object or array of objects

但是我也可以这样做:

 $html -> find('something') -> find('something_else');

,如果我正确理解方法链,这意味着find()返回$this,即本身。

这也是我的理解使用方法链接你返回$this,之后你使用getter方法实际返回一个值,你可以使用/想要的。例如:

对象->添加(1)->(2)添加-> getNumber ();

我在这里错过了什么?提前感谢!

实际上,对find的返回值调用find是没有意义的,因为该返回值应该是一个数组。

您最终可以添加第二个参数到您的find(string, array&),这样您可以:

$result1 = [];
$resilt2 = [];
$html -> find('something', $result1)
      -> fint('something else', $result2);
var_dump($result1, $result2);

:

public function find($search, & $output) {
    $output = ...
    return $this;
}

取决于你的品味。链式调用只有在你想在同一个对象上调用多个方法(不返回任何特别的)时才有用,这样可以避免每次都重写变量名,从而使代码更短。

编辑:如果你想这样做:

" $html -> find('div#results') -> find('li a'); "

您有一个问题,因为$html表示DOM,而find返回的值不是DOM,而是一组结果。find函数最终可以创建并返回一个较小的DOM,并将#result作为根(这将是与$html相同类的对象,而不是数组),然后调用find将对该新根而不是文档的根执行搜索,但这看起来有点不直观。

您在这里提到的链接类型涉及返回不是$this,而是一个表示找到的数据的新对象。诀窍是使用"魔法方法"和预定义的接口,使对象可用,就好像是一个数组或标量一样。

SimpleXML扩展广泛使用了这个概念,以便每个对象可以同时以多种方式使用:

  • __toString(),以便转换为字符串,或在像echo这样的明确字符串上下文中使用,为您提供XML节点的文本内容
  • ArrayAccess,以便您可以使用$a['href']访问属性,$li[42]访问多个匹配节点中的一个
  • 迭代器,以便您可以在多个匹配
  • foreach
  • __get()__set()通过标签名
  • 搜索和覆盖子元素

(实际上,SimpleXML是一个二进制扩展,所以有点欺骗,但理论上它的大部分功能可以在纯PHP中使用上述实现。)

例如这个语句:

echo $simplexml_element->foo[42]->bar['baz'];

似乎包含数组、散列和字符串,但实际上是一个完整的对象调用链,如下所示:

echo $simplexml_element->__get('foo')->offsetGet(42)->__get('bar')->offsetGet('baz')->__toString();