帮助理解面向对象的PHP有点帮助

时间:2012-09-22 03:48:35

标签: php oop

  

可能重复:
  PHP method chaining?

我对PHP和OOP比较陌生,而且我无法理解在我的数据库代码中弹出的重复结构。

我理解如何创建一个类,实例化它,以及访问属性和方法,但是$myobject->function()现在和我一样复杂。

这个结构是什么?

$myobject->function()->something。我越来越多地看到这一点,特别是当我开始围绕mysql PDO查询。例如:

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

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

6 个答案:

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

?>

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$ and window._$。你会看到它的许多成员方法都返回this(或者返回另一个方法,然后返回this)。反过来。当jQuery首次亮相时,这是许多“Javascript”开发人员第一次看到这种模式。这需要一些时间来适应。 :)

在jQuery中,在许多情况下,它应该为方法链提供良好的性能提升(例如,在时序很重要的动画队列中)。我不知道PHP是否就是这种情况,但这完全有可能。我在浏览器中比在服务器上更多,所以我在PHP中没有看到它。但重点是,这是一个需要掌握的权力概念。