PHP-Methodenverkettung oder fließende Schnittstelle?

Lesezeit: 8 Minuten

PHP Methodenverkettung oder fliesende Schnittstelle
Sanjay Khatri

Ich verwende PHP 5 und habe von einer neuen Funktion im objektorientierten Ansatz gehört, die als „Methodenverkettung“ bezeichnet wird. Was ist es genau? Wie setze ich es um?

  • Ich würde sagen, die meisten, wenn nicht alle dieser Fragen beziehen sich auf die technischen Aspekte der Verkettung, hier geht es genauer darum, wie man dies erreicht.

    – Kristoffer Sall-Storgaard

    16. September 2010 um 7:39 Uhr


  • @Kristoffer das OP hätte anhand dieser Fragen leicht herausfinden können, wie es erreicht wird.

    – Gordon

    16. September 2010 um 7:46 Uhr

  • @Kstoffer aber auch gesucht Methodenverkettung von PHP bei Google hätte dem OP a gegeben Lernprogramm von Salathe als allererstes Ergebnis. Es macht mir nichts aus, einfache Fragen zu beantworten, aber manche Leute sind einfach zu faul.

    – Gordon

    16. September 2010 um 8:00 Uhr


  • Ich lege Ihnen den endgültigen Entscheidungsbaum zur Verkettung von Methoden zur Durchsicht vor

    – rdlowrey

    15. August 2012 um 6:30 Uhr

PHP Methodenverkettung oder fliesende Schnittstelle
Kristoffer Sall-Storgaard

Es ist wirklich ziemlich einfach. Sie haben eine Reihe von Mutator-Methoden die alle das ursprüngliche (oder andere) Objekt zurückgeben. Auf diese Weise können Sie weiterhin Methoden für das zurückgegebene Objekt aufrufen.

<?php
class fakeString
{
    private $str;
    function __construct()
    {
        $this->str = "";
    }
    
    function addA()
    {
        $this->str .= "a";
        return $this;
    }
    
    function addB()
    {
        $this->str .= "b";
        return $this;
    }
    
    function getStr()
    {
        return $this->str;
    }
}


$a = new fakeString();


echo $a->addA()->addB()->getStr();

Dies gibt “ab” aus

Probieren Sie es online aus!

  • Dies wird manchmal auch als Fluent Interface bezeichnet

    – Nithesh Chandra

    16. September 2010 um 6:31 Uhr

  • @Nitesh das ist falsch. Fließende Schnittstellen verwenden Methodenverkettung als ihr primärer Mechanismus, aber es ist nicht das gleiche. Die Methodenverkettung gibt einfach das Host-Objekt zurück, während eine Fluent-Schnittstelle darauf abzielt, eine zu erstellen DSL. Ex: $foo->setBar(1)->setBaz(2) vs $table->select()->from('foo')->where('bar = 1')->order('ASC). Letzteres erstreckt sich über mehrere Objekte.

    – Gordon

    16. September 2010 um 7:32 Uhr


  • öffentliche Funktion __toString() { return $this->str; } Dies erfordert nicht die letzte Methode “getStr()”, wenn Sie die Kette bereits ausgeben.

    – Schriftart

    22. April 2014 um 7:01 Uhr

  • @tfont Stimmt, aber dann führen wir magische Methoden ein. Ein Konzept nach dem anderen sollte ausreichen.

    – Kristoffer Sall-Storgaard

    22. April 2014 um 8:49 Uhr

  • Seit PHP 5.4 ist das sogar möglich alles in einer Zeile: $a = (new fakeString())->addA()->addB()->getStr();

    – Philzen

    1. Juni 2015 um 18:49 Uhr


Grundsätzlich nehmen Sie ein Objekt:

$obj = new ObjectWithChainableMethods();

Rufen Sie eine Methode auf, die a effektiv ausführt return $this; Am Ende:

$obj->doSomething();

Da es dasselbe Objekt zurückgibt, oder besser gesagt a Hinweis für dasselbe Objekt können Sie weiterhin Methoden derselben Klasse vom Rückgabewert aufrufen, wie folgt:

$obj->doSomething()->doSomethingElse();

Das ist es wirklich. Zwei wichtige Dinge:

  1. Wie Sie bemerken, ist es nur PHP 5. Es wird in PHP 4 nicht richtig funktionieren, weil es Objekte nach Wert zurückgibt und das bedeutet, dass Sie Methoden für verschiedene Kopien eines Objekts aufrufen, was Ihren Code beschädigen würde.

  2. Auch hier müssen Sie das Objekt in Ihren verkettbaren Methoden zurückgeben:

    public function doSomething() {
        // Do stuff
        return $this;
    }
    
    public function doSomethingElse() {
        // Do more stuff
        return $this;
    }
    

  • Könntest du tun return &$this in PHP4?

    – Alex

    16. September 2010 um 6:18 Uhr

  • @alex: Ich habe gerade kein PHP 4 zum Testen, aber ich bin mir ziemlich sicher, dass es nicht so ist.

    – BoltClock

    16. September 2010 um 6:23 Uhr


  • Das dachte ich auch nicht, aber es sollte richtig funktionieren? Vielleicht, wenn PHP4 nicht so PHP4-artig wäre.

    – Alex

    16. September 2010 um 6:26 Uhr

PHP Methodenverkettung oder fliesende Schnittstelle
mwangaben

Versuchen Sie diesen Code:

<?php
class DBManager
{
    private $selectables = array();
    private $table;
    private $whereClause;
    private $limit;

    public function select() {
        $this->selectables = func_get_args();
        return $this;
    }

    public function from($table) {
        $this->table = $table;
        return $this;
    }

    public function where($where) {
        $this->whereClause = $where;
        return $this;
    }

    public function limit($limit) {
        $this->limit = $limit;
        return $this;
    }

    public function result() {
        $query[] = "SELECT";
        // if the selectables array is empty, select all
        if (empty($this->selectables)) {
            $query[] = "*";  
        }
        // else select according to selectables
        else {
            $query[] = join(', ', $this->selectables);
        }

        $query[] = "FROM";
        $query[] = $this->table;

        if (!empty($this->whereClause)) {
            $query[] = "WHERE";
            $query[] = $this->whereClause;
        }

        if (!empty($this->limit)) {
            $query[] = "LIMIT";
            $query[] = $this->limit;
        }

        return join(' ', $query);
    }
}

// Now to use the class and see how METHOD CHAINING works
// let us instantiate the class DBManager
$testOne = new DBManager();
$testOne->select()->from('users');
echo $testOne->result();
// OR
echo $testOne->select()->from('users')->result();
// both displays: 'SELECT * FROM users'

$testTwo = new DBManager();
$testTwo->select()->from('posts')->where('id > 200')->limit(10);
echo $testTwo->result();
// this displays: 'SELECT * FROM posts WHERE id > 200 LIMIT 10'

$testThree = new DBManager();
$testThree->select(
    'firstname',
    'email',
    'country',
    'city'
)->from('users')->where('id = 2399');
echo $testThree->result();
// this will display:
// 'SELECT firstname, email, country, city FROM users WHERE id = 2399'

?>

  • das nenne ich mal eine gute erklärung…verkettungsmethoden bescheren mir immer gänsehaut!!

    – MEINE

    12. Februar 2016 um 13:24 Uhr

  • Wie ich (innerhalb der Methode) die ersten und letzten Elemente (Aufrufe) in der Kette identifiziere. Denn manchmal ist dies jetzt nur eine Liste von Operationen, die der Reihe nach ausgeführt werden sollen, aber etwas, das nach dem Sammeln aller Elemente erledigt werden sollte. Als würde man hier eine SQL-Abfrage ausführen – aber Vorsicht, Sie könnten mehrere verkettete Aufrufe für ein Objekt ausführen! Erster und Letzter in jedem.

    – Andrés

    4. April 2018 um 22:45 Uhr

Ein weiterer Weg zur statischen Methodenverkettung:

class Maker 
{
    private static $result      = null;
    private static $delimiter=".";
    private static $data        = [];

    public static function words($words)
    {
        if( !empty($words) && count($words) )
        {
            foreach ($words as $w)
            {
                self::$data[] = $w;
            }
        }        
        return new static;
    }

    public static function concate($delimiter)
    {
        self::$delimiter = $delimiter;
        foreach (self::$data as $d)
        {
            self::$result .= $d.$delimiter;
        }
        return new static;
    }

    public static function get()
    {
        return rtrim(self::$result, self::$delimiter);
    }    
}

Berufung

echo Maker::words(['foo', 'bob', 'bar'])->concate('-')->get();

echo "<br />";

echo Maker::words(['foo', 'bob', 'bar'])->concate('>')->get();

1647031451 861 PHP Methodenverkettung oder fliesende Schnittstelle
alexn

Methodenverkettung bedeutet, dass Sie Methodenaufrufe verketten können:

$object->method1()->method2()->method3()

Das bedeutet, dass Methode1() ein Objekt zurückgeben muss und Methode2() das Ergebnis von Methode1() erhält. Method2() übergibt dann den Rückgabewert an method3().

Guter Artikel: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html

  • Die Erklärung ist etwas daneben. Die Rückgabewerte werden nicht herumgereicht. Die Methoden geben einfach das Host-Objekt zurück.

    – Gordon

    16. September 2010 um 8:19 Uhr

  • @Gordon Nun, das Hostobjekt wird nicht zurückgegeben. Jedes Objekt kann zurückgegeben und verkettet werden.

    – alexn

    16. September 2010 um 14:38 Uhr


  • Dann würde ich argumentieren, dass es keine Methodenverkettung im Sinne von Fowler ist, z Make-Modifikatormethoden geben das Hostobjekt zurück, sodass mehrere Modifikatoren in einem einzigen Ausdruck aufgerufen werden können. – Wenn Sie andere Objekte zurückgeben, handelt es sich eher um ein Fluent Interface 🙂

    – Gordon

    16. September 2010 um 14:58 Uhr


  • Wow, mir ist klar, dass ich einen fast 8 Jahre alten Beitrag kommentiere. Aber Ihr Link, den Sie dort haben, leitet auf eine andere Website weiter. Nur zur Info.

    – willbeeler

    19. Oktober 2017 um 18:41 Uhr

  • hier ist das Original Beitrag von Fowler aus dem Jahr 2005wobei sowohl Fluent Interface als auch Method Chaining erwähnt werden:

    – Matt Smith

    6. Februar um 13:59 Uhr

1647031451 302 PHP Methodenverkettung oder fliesende Schnittstelle
Bärenfell

Es gibt 49 Codezeilen, mit denen Sie Methoden wie folgt über Arrays verketten können:

$fruits = new Arr(array("lemon", "orange", "banana", "apple"));
$fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key) {
     echo $key.': '.$value."\r\n";
});

Sehen Sie sich diesen Artikel an, der Ihnen zeigt, wie Sie alle siebzig array_-Funktionen von PHP verketten.

http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html

  • Die Erklärung ist etwas daneben. Die Rückgabewerte werden nicht herumgereicht. Die Methoden geben einfach das Host-Objekt zurück.

    – Gordon

    16. September 2010 um 8:19 Uhr

  • @Gordon Nun, das Hostobjekt wird nicht zurückgegeben. Jedes Objekt kann zurückgegeben und verkettet werden.

    – alexn

    16. September 2010 um 14:38 Uhr


  • Dann würde ich argumentieren, dass es keine Methodenverkettung im Sinne von Fowler ist, z Make-Modifikatormethoden geben das Hostobjekt zurück, sodass mehrere Modifikatoren in einem einzigen Ausdruck aufgerufen werden können. – Wenn Sie andere Objekte zurückgeben, handelt es sich eher um ein Fluent Interface 🙂

    – Gordon

    16. September 2010 um 14:58 Uhr


  • Wow, mir ist klar, dass ich einen fast 8 Jahre alten Beitrag kommentiere. Aber Ihr Link, den Sie dort haben, leitet auf eine andere Website weiter. Nur zur Info.

    – willbeeler

    19. Oktober 2017 um 18:41 Uhr

  • hier ist das Original Beitrag von Fowler aus dem Jahr 2005wobei sowohl Fluent Interface als auch Method Chaining erwähnt werden:

    – Matt Smith

    6. Februar um 13:59 Uhr

1647031452 59 PHP Methodenverkettung oder fliesende Schnittstelle
pavelbere

Eine fließende Schnittstelle ermöglicht es Ihnen, Methodenaufrufe zu verketten, was zu weniger typisierten Zeichen führt, wenn Sie mehrere Operationen auf dasselbe Objekt anwenden.

class Bill { 

    public $dinner    = 20;

    public $desserts  = 5;

    public $bill;

    public function dinner( $person ) {
        $this->bill += $this->dinner * $person;
        return $this;
    }
    public function dessert( $person ) {
        $this->bill += $this->desserts * $person;
        return $this;
    }
}

$bill = new Bill();

echo $bill->dinner( 2 )->dessert( 3 )->bill;

991760cookie-checkPHP-Methodenverkettung oder fließende Schnittstelle?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy