3

重複の可能性:
PHP メソッドの連鎖?

私は PHP と OOP に比較的慣れていないので、データベース コードに出現する繰り返し構造を理解するのに苦労しています。

クラスを作成し、インスタンス化し、プロパティとメソッドにアクセスする方法を理解していますが$myobject->function()、今のところ私にとっては複雑です。

この構造は何ですか?

$myobject->function()->something. 特にmysql PDOクエリに頭を悩ませ始めているため、これを繰り返し目にすることがますます増えています。例えば:

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

ここで何が起こっているのですか?クラス内の複数のメソッドの 1 つの呼び出しをチェーンするだけですか、それともそれらのサブ関数function1()ですか? クラス定義はどのようになりますか?

4

6 に答える 6

6

これは、 FluentInterfaceと呼ばれるデザインパターンです。これは、jQueryなど、それを使用するいくつかの注目すべきフレームワークを通じて普及しています。これは、コンパクトで読みやすいコード(場合によっては)を作成するための巧妙なトリックですが、多くのデザインパターンと同様に、すべての状況に適しているわけではありません。

->シンボルは実際には単なる演算子です。+または-を使用して数値を操作する方法と同様に、->演算子はオブジェクトとメンバーを操作できます。PHPインタープリターは、のように式5 + 4を単純化することができます。また9、のように式を単純化することもでき$a->bます。式は、という名前のメンバーの$a->b内部を探すことによって評価されます。$ab

+演算子を式で複数回使用できるのと同じように、たとえば5 + 2 + 7->演算子も複数回使用できます。PHPインタープリターは、+演算子に対して結合性が残されています。つまり、5 + 2 + 7作成されたかのように評価され(5 + 2) + 7、はに評価され7 + 7、次にはに評価され14ます。

->演算子も結合性のままです。したがって、のような式$a->b->cは前の例と同様の方法で解釈されます。最初にインタプリタはで呼び出され$a->bたメンバーを探して評価ba、次にその中で呼び出されたメンバーを探しcます。$a->bこれは、実際にオブジェクトに評価されることを前提としています。そうでない場合、PHPインタープリターは「非オブジェクトのプロパティを取得しようとしています」というエラーを表示します。

このパラダイムは無期限に拡張できます:$a->b->c->d->e->f->g->....など。

Fluent Interfaceデザインパターンでは、これはすべてのインスタンスメソッドがインスタンスを返すようにすることで実装されます。したがって、を$a->b()返します$a。したがって、を呼び出してから呼び出すのと$a->b()->c()まったく同じです。$a->b()$a->c()

前者の方が後者より読みやすいと考える人もいます。それが真実である場合もあれば、そうでない場合もあります。ほとんどのデザインパターンと同様に、このパターンを使用するかどうかを決定する際には、適切な判断を下す必要があります。このパターンは、インスタンスメソッドが純粋に副作用のために呼び出された場合にのみ機能することに注意してください。インスタンス自体以外のインスタンスメソッドから他の値を返すことはできません。そうしないと、流暢なインターフェイスが壊れてしまいます。

于 2012-09-22T04:12:52.520 に答える
4

$myobject->function()オブジェクトを返す場合、->somethingそのオブジェクトのフィールドにアクセスします。

基本的に、このプログラミング方法の主な概念は、オブジェクトにはデータと、含まれるデータと対話するためのメソッド (または「関数」) が含まれているということです。これらのコンテナは便利に渡すことができます。PHP は省略形を提供しているので、すべてを変数に代入する必要はありません。

オブジェクトを返すことは機能を階層化する方法であるため、クエリ メソッドを持つ PDO オブジェクトは行オブジェクトを返す場合があります。行オブジェクトには独自のメソッド セット (列の値を取得するためなど) があるため、これらのメソッドを呼び出すことができます。

そう:

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

実際には、次の省略形です。

$result = $pdo->queryOneRow(...);
$result->getValue(<some column>)
于 2012-09-22T03:55:48.473 に答える
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は、あるクラスのオブジェクトを返す必要があります。

お役に立てば幸いです...

于 2012-09-22T04:01:00.600 に答える
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();  
于 2012-09-22T04:02:40.513 に答える
0

-> 構文は、クラスのメソッドとメンバーにアクセスするために使用する演算子です。このようなことをすると:

$someObject -> function1(arg) -> function2(arg) ... 返されたオブジェクトにさらにアクセスしているだけです。

クラス Bike があるとします。この自転車には、float をパラメーターとして受け取る 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);

それで、ここで何が起こっているのですか?まず、パラメータの存在は関係ありません。持っているかどうかにかかわらず、メソッドはこのオブジェクトを返すことができます。

このバイクは自分自身を呼び出し元に返すため、非常に多くの -> 演算子を使用できます。したがって、MyBike -> SpeedUp() を呼び出すと、これは MyBike を返すため、2 回目の SpeedUp 呼び出しでは、基本的に myBike -> SpeedUp(40.3) になり、同じ自転車が再び返されるため、速度を下げることができます。同じ行。

免責事項: この例は非常に一般的なものですが、質問に対する答えを説明するのに役立ちます。

于 2012-09-22T03:57:43.257 に答える
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.extend、 、jQuery.fn/jQuery.fn.init$およびwindow._$. そのメンバ メソッドの多くが返さthisれます (または、別のメソッドが返されて が返されますthis)。順番があります。jQuery が登場したとき、多くの「Javascript」開発者がこのパターンを見たのはこれが初めてでした。慣れるまでに時間がかかりました。:)

jQuery では、多くの条件下で、メソッド チェーンのパフォーマンスが大幅に向上するはずです (たとえば、タイミングが重要なアニメーション キューなど)。それが PHP の場合かどうかはわかりませんが、それは完全に可能です。私はサーバーよりもブラウザを使っているので、PHP ではあまり見たことがありません。しかし要点は、それは把握すべき力の概念だということです。

于 2012-09-22T04:54:43.343 に答える