php 这些多个/连接的方法调用是什么意思?[duplicate]

gxwragnw  于 2023-01-12  发布在  PHP
关注(0)|答案(6)|浏览(152)
    • 此问题在此处已有答案**:

PHP method chaining or fluent interface?(10个答案)
2天前关闭。
我知道如何创建类、示例化类以及访问属性和方法,但是$myobject->function()对我来说就像现在一样复杂。
这是什么结构?
$myobject->function()->something。我越来越多地反复看到这种情况,特别是当我开始把我的头缠在PDO查询上时。

$query->function1($arg)
  ->function2($arg)
  ->function3($arg);

这里发生了什么?它只是简单地链接了类中多个方法的一个调用,还是function1()的那些子函数?类定义看起来会是什么样子?

czfnxgou

czfnxgou1#

这是一种叫做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这样的表达式的解释方式与上一个示例类似:首先解释器通过在a中寻找一个名为b的成员来计算$a->b,然后它在中寻找一个名为c的成员!这里假设$a->b实际上计算为一个对象;如果不匹配,PHP解释器会给予一个错误:“正在尝试获取非对象的属性”。
这个范例可以无限扩展:$a->b->c->d->e->f->g->....等等。
在Fluent接口设计模式中,这是通过让所有示例方法返回示例来实现的,因此$a->b()返回$a,因此$a->b()->c()与调用$a->b()然后调用$a->c()完全相同。
有些人认为前者比后者更可读。在某些情况下,这是正确的,但在其他情况下,它不是。像大多数设计模式,你需要使用良好的判断时,决定是否使用这种模式。请记住,这种模式只能工作,如果调用示例方法纯粹是为了他们的副作用。你不能返回任何其他值从一个示例方法除了示例本身。否则会破坏流畅的界面。

u5i3ibmn

u5i3ibmn2#

$myobject->function()正在返回一个对象,则->something将访问该对象上的字段。
基本上,这种编程方法的主要概念是一个对象包含数据和与所包含数据交互的方法(或“函数”)。这些容器可以方便地传递。PHP提供了一些简化方法,因此您不必将所有内容都赋给变量。
返回对象是分层功能的一种方式,所以你的PDO对象,它有一个查询方法,可以返回一个行对象。行对象有它自己的方法集(例如,用于获取列值),所以你可以调用这些方法。
因此:

$pdo->queryOneRow(...)->getValue(<some column>)

实际上只是简单的表达:

$result = $pdo->queryOneRow(...);
$result->getValue(<some column>)
s6fujrry

s6fujrry3#

$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必须返回某个类的对象。
希望能有所帮助...

qnakjoqk

qnakjoqk4#

下面是一个简单的演示,有点意思:

<?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();

?>

http://codepad.org/zlQEMPqK
如果您对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.extendjQuery.fn/jQuery.fn.init$window._$。你会看到它的许多成员方法返回this(或者返回另一个方法,该方法反过来返回this)。依次地,当jQuery首次亮相时,那是许多“Javascript”开发人员第一次看到这种模式。它花了一些时间来适应。:)
在jQuery中,在许多情况下,它应该给方法链给予很好的性能提升(例如,在动画队列中,时间很重要)。我不知道PHP中是否是这样,但这是完全可能的。我更多地使用浏览器而不是服务器,所以我在PHP中没有看到太多。但关键是,这是一个需要掌握的强大概念。

epfja78i

epfja78i5#

语法是用来访问类的方法和成员的操作符。当你这样做的时候:
$someObject -〉function 1(arg)-〉function 2(arg)...您只是进一步访问返回的对象。
假设你有一个类Bike,这个类有一个名为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);

那么这是怎么回事呢?,首先,参数的存在是无关紧要的,不管你有没有参数,你的方法仍然可以返回这个对象。
你可以使用这么多-〉运算符,因为这个bike会自动返回给调用者,所以当你调用MyBike -〉SpeedUp()时,它会返回MyBike,所以在第二个SpeedUp调用中,它本质上是myBike -〉SpeedUp(40. 3),因为它会返回相同的bike,所以你可以在同一行中减慢它的速度.
免责声明:这个例子确实是通用的,但它应该有助于说明问题的答案。

mlnl4t2r

mlnl4t2r6#

在面向对象编程中,对象可以有多个示例,这些示例中的属性可以有不同的值。
例如

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();

相关问题