2010-02-21 4 views
12

Généralement, dans beaucoup de cadres, vous pouvez trouver des exemples de création d'une requête en utilisant le générateur de requête. Souvent, vous verrez:Méthodes Chaînes PHP OOP

$query->select('field'); 
$query->from('entity'); 

Cependant, dans certains cadres, vous pouvez aussi le faire comme ça

$object->select('field') 
     ->from('table') 
     ->where(new Object_Evaluate('x')) 
     ->limit(1) 
     ->order('x', 'ASC'); 

Comment faites-vous réellement ce genre de chaînes?

Répondre

18

Ceci est appelé Fluent Interface - il y a une example in PHP sur cette page.

L'idée de base est que chaque méthode (que vous voulez être en mesure de la chaîne) de la classe doit retourner $this - ce qui rend possible d'appeler d'autres méthodes de cette même classe sur le revenu $this.

Et, bien sûr, chaque méthode a accès aux propriétés de l'instance actuelle de la classe - ce qui signifie que chaque méthode peut "ajouter des informations" à l'instance en cours.

+0

De rien :-) ;; oui, chaque méthode peut définir/modifier des propriétés, et la méthode "last" est souvent utilisée pour "exécuter" ce que les méthodes précédentes ont été appelées à configurer. –

+0

Je ne suis pas sûr que l'utilisation d'une interface fluide facilitera toujours la lecture du code ;;; quand il est utilisé pour construire une requête SQL, par exemple, cela a du sens; mais quand les méthodes ne sont pas vraiment liées, pas si sûres - dépend de la situation, je suppose ;;; une bonne chose étant que même si vos méthodes retournent '$ this', elles peuvent être appelées" de façon typique ". –

+0

Doit-il retourner '$ this'? Ne peut-il pas retourner '$ that' et continuer à partir de là? –

2
class c 
{ 
    function select(...) 
    { 
    ... 
    return $this; 
    } 
    function from(...) 
    { 
    ... 
    return $this; 
    } 
    ... 
} 

$object = new c; 
7

Fondamentalement, vous devez faire chaque méthode dans la classe retourne l'instance:

<?php 

class Object_Evaluate{ 
    private $x; 
    public function __construct($x){ 
     $this->x = $x; 
    } 
    public function __toString(){ 
     return 'condition is ' . $this->x; 
    } 
} 
class Foo{ 
    public function select($what){ 
     echo "I'm selecting $what\n"; 
     return $this; 
    } 
    public function from($where){ 
     echo "From $where\n"; 
     return $this; 
    } 
    public function where($condition){ 
     echo "Where $condition\n"; 
     return $this; 
    } 
    public function limit($condition){ 
     echo "Limited by $condition\n"; 
     return $this; 
    } 
    public function order($order){ 
     echo "Order by $order\n"; 
     return $this; 
    } 
} 

$object = new Foo; 

$object->select('something') 
     ->from('table') 
     ->where(new Object_Evaluate('x')) 
     ->limit(1) 
     ->order('x'); 

?> 

Ceci est souvent utilisé comme un pur régal pour les yeux, mais je suppose qu'il a ses usages valables aussi bien.

+0

Cas d'utilisation: '$ setup = $ Objet-> add_component ($ component_property) -> configure ($ component_properties);' Où Object :: add_component() retourne l'objet Component ajouté en tant que propriété de $ Object (par ex. array), et il est configuré avec la méthode Component :: configure(). Sans chaînage, nous devrions déterminer ce dernier élément ajouté au tableau $ Object-> Components, puis obtenir l'objet Component de cette façon. – AVProgrammer

+0

@AVProgrammer - Votre exemple n'utilise pas 'return $ this', n'est-ce pas? –

+0

Oui, l'objet Component le fait pour autoriser la méthode configure(). – AVProgrammer