2010-02-21 3 views
0

Je veux être en mesure de faire quelque chose comme ceci:Comment créer une requête mysql via un ensemble de méthodes PHP OOP?

$table_object->getRows()->where($wer)->or($or)->orderBy('field', 'DESC'); 

Si j'étais sûr que toutes les méthodes seront appelées à chaque fois et dans cet ordre, il serait alors simple et je peux retourner une instance de l'objet lui-même à chaque appel de méthode afin que la requête soit générée et finalement exécutée à la méthode orderBy. Cependant, je veux la classe pour être en mesure d'exécuter également des requêtes comme ceci:

$table_object->getRows()->where($wer); 

Le code suivant travaillerait pour le premier exemple de code (lorsque toutes les méthodes sont appelées), mais pas avec la seconde où seule méthode où est appelé après getRows. Il ne renvoie qu'une instance de lui-même.

class DatabaseTable extends Database 
{ 
protected $table_name; 
protected $query; 

public function getRows() 
{ 
    return ($this instanceof self)? $this : false; 
} 

public function where(array $where) 
{ 

    foreach ($where as $field => $value){ 
    $w[] = $field . ' = "' . $this->escapeString($value) . '"'; 
    } 

    $this->query = "SELECT * FROM {$this->table_name} WHERE " . join($w, ' AND ')); 

    return $this; 
} 

public function or(array $Clause) 
{ 
    foreach ($clause as $field => $value){ 
    $o[] = $field . ' = "' . $this->escapeString($value) . '"'; 
    } 

    $this->query .= join($w, ' AND '); 

    return $this; 
} 

public function orderBy($field, $type) 
{ 
    $this->query .= " ORDER BY $field $type "; 
    $this->executeQuery($this->query); 
} 

} 

ignorera toutes les erreurs mineures - (i na pas vérifier si cela a fonctionné pour sûr, mais il devrait.) comment puis-je y parvenir?

+1

Désolé si je semble que je suis à la traîne, mais $ table_object-> getRows() -> Où ($ wer) -> OR ($ ou) -> orderBy ('field', 'DESC'); Vous avez essentiellement écrit la requête entière là. Pourquoi ne pas simplement écrire "SELECT * WHERE {$ wer} OU {$ ou} ORDER BY le champ DESC" ._.? – Warty

+0

@ItzWarty parce qu'il veut probablement un wrapper OOP DB-agnostique pour cela. – Gordon

+2

Je suis d'accord avec ltzWarty. Il n'y a pas de bonne raison de prendre un langage spécifique à un domaine décent et de le transformer en un désordre OOP laid. – Imbue

Répondre

6

Ne pas passer par ce tracas de construire votre propre quand vous pouvez utiliser Doctrine

$q = Doctrine_Query::create() 
    ->from('User u') 
    ->leftJoin('u.Phonenumbers p'); 

ou Propel

$c = new Criteria(); 
$c->add(AuthorPeer::FIRST_NAME, "Karl"); 
$c->add(AuthorPeer::LAST_NAME, "Marx", Criteria::NOT_EQUAL); 
$authors = AuthorPeer::doSelect($c); 

ou Zend_Db_Query.

$select = $db->select() 
       ->from(array('p' => 'products'), 
         array('product_id', 'product_name')) 
       ->join(array('l' => 'line_items'), 
         'p.product_id = l.product_id'); 

Si elles ne vous conviennent pas pour une raison quelconque, vous pouvez les utiliser comme point de départ sur la façon de rouler votre propre.

+0

De jolis exemples :) –

+2

@David ces documents sont issus de la documentation des frameworks respectifs – Gordon

+0

Mon but ici était plutôt d'apprendre comment c'est fait plutôt que de recréer .. Je vais y jeter un oeil. – shxfee

4

Vous voudrez peut-être consulter le composant Zend_Db_Select de Zend Framework, qui fournit une interface OO aux requêtes SQL. Zend_Db fournit également un certain nombre d'autres fonctions de base de données utiles.

+0

:/ne me suis jamais venu à l'idée d'y jeter un coup d'œil. – shxfee

0

Comme d'autres l'ont mentionné, vous ne devriez pas réinventer la roue quand un composant existe déjà et peut faire ce que vous voulez (Zend_Db_Select).

Mais si vous voulez toujours créer le vôtre, alors une possibilité est d'inclure une méthode Select ($ fields) qui est ajoutée à la fin de votre requête et qui peut prendre une liste de champs à sélectionner ou "*" pour tous. Cette méthode select() serait ce qui exécute réellement le code sql pour vous. Oui, je sais que ça ne ressemblerait pas exactement à SQL en ce que le select serait à la fin, mais c'est une solution facile à mettre en place. En aparté, ce que vous essayez de faire est de construire une interface fluide ou DSL, il vaudrait donc la peine de lire un peu dessus, pour voir comment certaines implémentations sont construites.