可能重复:
PHP method chaining?
我对PHP和OOP比较陌生,而且我无法理解在我的数据库代码中弹出的重复结构。
我理解如何创建一个类,实例化它,以及访问属性和方法,但是$myobject->function()
现在和我一样复杂。
这个结构是什么?
$myobject->function()->something
。我越来越多地看到这一点,特别是当我开始围绕mysql PDO查询。例如:
$query->function1($arg)
->function2($arg)
->function3($arg);
这里发生了什么?是简单地在类中链接多个方法的一个调用,还是function1()
的子函数?类定义会是什么样的?
答案 0 :(得分:6)
这是一种名为Fluent Interface的设计模式。它通过一些使用它的着名框架(例如jQuery)而变得普及。这是编写紧凑,可读代码(在某些情况下)的巧妙技巧,但与许多设计模式一样,它并不适合所有情况。
->
符号实际上只是一个运算符。与+
或-
可用于操作数字的方式类似,->
运算符可以对对象和成员进行操作。 PHP解释器可以将5 + 4
之类的表达式简化为9
,并且它也可以简化$a->b
之类的表达式。通过在$a->b
内查找名为$a
的成员来评估表达式b
。
就像+
运算符可以在表达式中多次使用一样,例如5 + 2 + 7
,->
运算符也可以多次使用。 PHP解释器与+
运算符保持关联,这意味着它将5 + 2 + 7
计算为(5 + 2) + 7
,其值为7 + 7
,其值为14
,而->
的计算结果为$a->b->c
。 {1}}。
$a->b
运算符也是关联的。因此,像b
这样的表达式的解释方式与上一个示例类似:首先,解释器通过在a
中查找名为c
的成员来评估$a->b
,然后查看对于一个名为$a->b->c->d->e->f->g->....
的成员!这假定$a->b()
实际上评估对象;如果没有,那么PHP解释器会给你一个错误:“试图获取非对象的属性”。
这种范例可以无限延长:$a
等。
在Fluent Interface设计模式中,这是通过让所有实例方法返回实例来实现的。因此$a->b()->c()
会返回$a->b()
。因此,$a->c()
与调用{{1}}然后调用{{1}}完全相同。
有些人认为前者比后者更具可读性。在某些情况下这是真的,但在其他情况下则不然。像大多数设计模式一样,在决定是否使用此模式时,您需要使用良好的判断。请记住,只有实例方法纯粹因其副作用而被调用时,此模式才有效。除了实例本身之外,您不能从实例方法返回任何其他值,否则您将破坏流畅的界面。
答案 1 :(得分:5)
$myobject->function()
正在返回一个对象,->something
将访问该对象上的字段。
基本上,此编程方法的主要概念是对象包含与包含的数据交互的数据和方法(或“函数”)。这些容器可以方便地通过。 PHP为您提供了一些简写,因此您无需将所有内容分配给变量。
返回对象是一种分层功能的方法,因此具有查询方法的PDO对象可能会返回行对象。行对象有自己的一组方法(例如,用于获取列值),因此您可以调用这些方法。
所以:
$pdo->queryOneRow(...)->getValue(<some column>)
真的只是简写:
$result = $pdo->queryOneRow(...);
$result->getValue(<some column>)
答案 2 :(得分:1)
$query->function1($arg) ->function2($arg) ->function3($arg);
表示:
$some_object1 = $query->function1($arg);
$some_object2 = $some_object2->function2($arg);
$final_result = $some_object2->function3($arg);
所以你的函数1和函数2必须返回某个类的对象。
希望有帮助...
答案 3 :(得分:0)
- &gt;语法是用于访问类的方法和成员的运算符。当你做这样的事情时:
$ someObject - &gt; function1(arg) - &gt; function2(arg)...您只是进一步访问返回的对象。
假设你有一个类自行车。这个自行车有一个名为SpeedUp(arg)的方法,它以浮点数作为参数。 SpeedUp方法返回调用方法的对象($ this指针)。要稍微改变一下,我们将添加一个SlowDown(arg)方法。
class myBike
{
private function SpeedUp($arg)
{
//Do something with $arg, then return "this"...
return $this;
}
private function SlowDown($arg)
{
//Do somethign with $arg, then return "this".
return $this;
}
}
Bike myBike;
MyBike -> SpeedUp(50.3) -> SpeedUp(40.3) -> SlowDown(30.4);
那么这里发生了什么?首先,参数的存在是无关紧要的。无论您是否拥有它,您的方法仍然可以返回此对象。
你可以使用这么多 - &gt;操作员,因为这辆自行车将自己返回给来电者。所以当你打电话给MyBike时 - &gt; SpeedUp(),这将返回MyBike,所以在第二次SpeedUp调用中,它基本上是myBike - &gt; SpeedUp(40.3),因为它再次返回相同的自行车,你可以在同一行减速。
免责声明:此示例非常通用,但它应该有助于说明问题的答案。
答案 4 :(得分:0)
使用面向对象的编程,对象可以有多个实例。这些实例中的属性可以具有不同的值。
例如。
class Person {
public var $name;
public var $age:
public function simpleGetter() {
echo "name : ". $this->name;
echo "age : ". $this->age;
return $this;
}
public function addAgeByOne($instance = null) {
return ++$instance->age;
}
}
$student = new Person();
$student->name = "Student\'s name";
$student->age = 23;
$teacher = new Person();
$teacher->name = "Teacher\'s name";
$teacher->age = 45;
$student->simpleGetter(); // will display the property value from student instance
$teacher->simpleGetter(); // will display the property value from teacher instance
// yes this is chaining, it will first retrieve the results from simpleGetter() and then
// pass on to addAgeByOne
$student->simpleGetter()->addAgeByOne();
答案 5 :(得分:0)
这是一个有趣的简单演示:
<?php
class ChainMe {
public function hello() {
echo 'Hello ';
return $this;
}
public function good($is = false) {
if ($is === true) {
echo 'beautiful ';
}
return $this;
}
public function day() {
echo "world!\n\n";
return $this;
}
}
$happy = new ChainMe();
$happy
->hello()
->good(true)
->day();
$meh = new ChainMe();
$meh->hello()->good()->day();
?>
如果您对jQuery一直很熟悉并且曾经见过类似的东西:
jQuery('#my .awesome[selector]')
.fadeToggle('fast')
.addClass('rocks')
.fadeToggle();
然后你经历了链接。例如,查看源代码中的jQuery
变量定义:
// Define a local copy of jQuery
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
还有jQuery.extend
,jQuery.fn
/jQuery.fn.init
,$
and window._$
。你会看到它的许多成员方法都返回this
(或者返回另一个方法,然后返回this
)。反过来。当jQuery首次亮相时,这是许多“Javascript”开发人员第一次看到这种模式。这需要一些时间来适应。 :)
在jQuery中,在许多情况下,它应该为方法链提供良好的性能提升(例如,在时序很重要的动画队列中)。我不知道PHP是否就是这种情况,但这完全有可能。我在浏览器中比在服务器上更多,所以我在PHP中没有看到它。但重点是,这是一个需要掌握的权力概念。