Lerm-IT

Blog traitant de technologies informatiques. Logiciel libre, AdminSys, DevOps et GNU/Linux !

15 Sep 2008

[Zend Framework] Faire un join

Il se peut que vous rencontriez une erreur de type:

Select query cannot join with another table in /var/www/ etc ...

Ceci est dû à Zend Framework qui n’autorise pas par défaut de faire une simple jointure sur une table sous-jacente.

L’objet Zend_Db_Table_Select est destiné à sélectionner des données sur une table précise. Des jointures peuvent être faites, mais il n’est pas possible de sélectionner des colonnes ne faisant pas partie de la table sous-jacente. Cependant, ceci aurait pu être utile dans certains cas, et l’objet Zend_Db_Table_Select possède une clause spéciale déverrouillant cette limitation. Passez la valeur false à sa méthode setIntegrityCheck. Il est alors possible de sélectionner des colonnes hors table. Attention toutefois, l’objet row/rowset résultant sera verrouillé. Impossible d’y appeler save(), delete() ou même d’affecter une valeur à certains de ses champs. Une exception sera systématiquement levée.

Pour enlever cette protection vous devez spécifier setIntegrityCheck(false) dans votre requête.

Par exemple pour une classe simple de récupération de news j’ai :

> <?php
> 
> /**  
> * News  
> *  
> * @author Lermit  
> * @version 1  
> */
> 
> require_once 'Zend/Db/Table/Abstract.php';
> 
> class News extends Zend\_Db\_Table_Abstract {
> 
> protected $_name = 'news';  
> protected $\_primary = 'news\_id';  
> protected $_dependentTables = array("Users");  
> protected $_referenceMap = array(  
>     'Reporter' => array(  
>     'columns' => 'user_id',  
>     'refTableClass' => 'Users',  
>     'refColumns' => 'user_id'  
>     )  
> );
> 
> /**  
> * getLast  
> * retourne les $numberOfNews dernières news à partir de $start  
> * @author lermit  
> * @version 1  
> * @param $numberOfNews nombre de news  
> * @param $start à partir de la n-ieme news  
> * @return les news  
> */  
> public function getLast($numberOfNews,$start)  
> {  
>     $select = $this->select()  
>         ->setIntegrityCheck(false)  
>         ->from( array('n' => $this->\_name), array('text','date','user\_id'))  
>         ->join(array('u' =>'users'),'u.user\_id=n.user\_id','login')  
>         ->order('date DESC')  
>         ->limit($numberOfNews,$start);
> 
>     return $this->fetchAll($select);  
> }  
> }

Tout d’abord je spécifie le nom et la clef primaire de ma table puis les relations de jointure avec les autres tables.

$_dependentTable
tableau de la/les classe(s) de la(des) table(s) dépendante(s).
$_referenceMap
tableau de tableaux de dépendances. Chaque dépendance est listée sous la forme d’un tableau construisant comme suit :
'columns'
‘colonne de la classe courante’,
'refTableClass'
‘classe de la table à joindre’,
'refColumns'
‘colonne de la table à joindre’

Bref ma requête utilise bien ->setIntegrityCheck(false) ce qui m’enlèvera cette fâcheuse erreur !!