web-dev-qa-db-fra.com

PHP enchaînement de méthodes?

J'utilise PHP 5 et j'ai entendu parler d'une nouvelle fonctionnalité de l'approche orientée objet, appelée "méthode de chaînage". De quoi s'agit-il exactement? Comment puis-je l'implémenter?

153
Sanjay Khatri

C'est plutôt simple, vous avez une série de méthodes mutatrices qui toutes renvoient les objets originaux (ou autres), de cette façon vous pouvez continuer à appeler des méthodes sur l'objet renvoyé.

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

Cette sortie "ab"

Essayez-le en ligne!

310

Fondamentalement, vous prenez un objet:

$obj = new ObjectWithChainableMethods();

Appelez une méthode qui effectue efficacement un return $this; à la fin:

$obj->doSomething();

Puisqu'il renvoie le même objet, ou plutôt une référence au même objet, vous pouvez continuer à appeler des méthodes de la même classe à partir de la valeur renvoyée, comme suit:

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

C'est ça, vraiment. Deux choses importantes:

  1. Comme vous le constatez, il ne s'agit que de PHP 5. Cela ne fonctionnera pas correctement avec PHP 4 car il renvoie des objets par valeur et cela signifie que vous appelez des méthodes sur différentes copies d'un objet, ce qui briserait votre code.

  2. De nouveau, vous devez renvoyer l'objet dans vos méthodes chaînables:

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

Essayez ce 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'

?>
24
mwangaben

Le chaînage de méthodes signifie que vous pouvez chaîner des appels de méthodes:

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

Cela signifie que method1 () doit renvoyer un objet et que method2 () reçoit le résultat de method1 (). Method2 () passe ensuite la valeur de retour à method3 ().

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

11
alexn

Une autre manière de chaîner les méthodes statiques:

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

Appel

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

echo "<br />";

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

Il y a 49 lignes de code qui vous permettent d’enchaîner des méthodes sur des tableaux comme ceci:

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

Voir cet article qui vous montre comment chaîner les soixante-dix fonctions array_ de PHP.

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

6
Lukas Dong