Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 28-09-2007 10:40:37

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

[BUG] Zend_Db_Select ???

Salut à tous je pense qu'il y a un BUG dans Zend_Db
la classe Zend_Db_Select défini une methode query
celle-ci permet de spécifier le mode de retour des donnés Zend_Db::FETCH_OBJ Zend_Db::FETCH_ASSOC etc.
le peut de commentaire dispos disent que le retour est un Zend_Db_Statement (ou son équivalent PDO)

mais en regardant de plus près le code cette méthode ne crée pas un Statement mais appelle la méthode query de l'adaptateur. qui lui exécute la requête et ne fixe le FetchMode qu'après.

Si la requête contient des paramètres cette méthode sur Zend_Db_Select ne permet pas de passer le binding du coup on obtient un "Invalid parameter number: no parameters were bound"

si j'en crois le commentaire cette méthode ne devrait pas exécuter la requête mais retourner un statement.
et sur ce dernier je pourrais faire un execute.
ainsi

Code:

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $statment = $select->query(Zend_Db::FETCH_OBJ);
      $statment->execute(array('_param', 5));

mais dans les faits query exécute la requête.

Code:

    /**
     * @param integer $fetchMode OPTIONAL
     * @return PDO_Statement|Zend_Db_Statement
     */
    public function query($fetchMode = null)
    {
        $stmt = $this->_adapter->query($this); // <== On exécute ici la requête SANS le binding
        if ($fetchMode == null) {
            $fetchMode = $this->_adapter->getFetchMode();
        }
        $stmt->setFetchMode($fetchMode); // <== On fixe le fetchMode
        return $stmt;
    }

Si par contre je suis la logique des méthodes query des diverses classe de Zend_Db query doit exécuter la requête. il manque alors à cette méthode le paramètre binding pour faire ainsi

Code:

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $statment = $select->query(array('_param', 5),Zend_Db::FETCH_OBJ);

dans ce cas la méthode query doit être

Code:

    /**
     * @param integer $fetchMode OPTIONAL
     * @return PDO_Statement|Zend_Db_Statement
     */
    public function query($bind = array(), $fetchMode = null)
    {
        $stmt = $this->_adapter->query($this, $bind); // <== On exécute ici la requête AVEC le binding
        if ($fetchMode == null) {
            $fetchMode = $this->_adapter->getFetchMode();
        }
        $stmt->setFetchMode($fetchMode); // <== On fixe le fetchMode
        return $stmt;
    }

toujours est-il qu'il y a là une incohérence qui interdit d'utiliser la méthode query sur un select paramétré ce qui est une sacrée limitation car il faut alors systématiquement en passer par d'autres opérations plus complexes.
A+JYT

Dernière modification par sekaijin (28-09-2007 11:02:16)

Hors ligne

 

#2 28-09-2007 10:55:29

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [BUG] Zend_Db_Select ???

voici les deux solution que j'ai trouvé pour palier à cette difficulté
la première consiste à garder sous le coude le fetchMode d'utiliser la méthode fetchAll de l'adaptateur
puis de restituer le fetchMode

Code:

      $fetchMode = $this->_db->getFetchMode();
      $this->_db->setFetchMode(Zend_Db::FETCH_OBJ);

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $groups = $this->_db->fetchAll($select, array('_lowNameStart' => strtolower($nameStart).'%',
                                                    '_upNameStart' => strtoupper($nameStart).'%'));
      $this->_db->setFetchMode($fetchMode);

la seconde consiste à passer par un statement qui lui aura sont propre fetchMode

Code:

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $statment = $this->_db->prepare($select);
      $statment->setFetchMode(Zend_Db::FETCH_OBJ);
      $statment->execute(array('_lowNameStart' => strtolower($nameStart).'%',
                               '_upNameStart' => strtoupper($nameStart).'%'));
      $groups = $statment->fetchAll();

A+JYT

Dernière modification par sekaijin (28-09-2007 11:07:21)

Hors ligne

 

#3 28-09-2007 20:04:33

Julien
Membre
Date d'inscription: 16-03-2007
Messages: 501

Re: [BUG] Zend_Db_Select ???

Si tu crois (je n'ai pas analysé ton code, désolé) avoir trouvé un bug, vérifie le bugtracker de ZF

Il est possible que celui-ci soit déja reporté.
Dans le cas contraire, tu peux toi-même le reporté, mais il faut signer le CLA avant.

Si j'ai le temps, je l'analyserai d'ici peu ;-)

Hors ligne

 

#4 28-09-2007 21:05:30

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [BUG] Zend_Db_Select ???

je regarderais ça mais il y a une incohérence c'est sur

Hors ligne

 

#5 30-09-2007 14:56:02

Julien
Membre
Date d'inscription: 16-03-2007
Messages: 501

Re: [BUG] Zend_Db_Select ???

Ok j'ai analysé ton code et je comprends.
query() execute la requête, ça a toujours été ainsi, mais il est vrai que la méthode query() de Zend_Db_Select diffère de celle de l'adapter; et qu'on ne peut pas lui passer de paramètres pour un binding.
C'est incohérent comme tu le soulignes, j'ouvre un ticket improvement sur le tracker (bug ZF-2017)

Merci :-)

PS : c'est pas array('_param', 5) , mais array('_param'=>5) ^^

Hors ligne

 

#6 02-10-2007 08:57:26

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [BUG] Zend_Db_Select ???

C'est bien ainsi que je l'avais compris aussi.
mais il serait triste de perdre la possibilité de définir le fetchMode pour la query.
je verrais bien pour rester cohérent avec le reste quelque chose comme

Code:

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $statment = $select->query(array('_param' => 5),Zend_Db::FETCH_OBJ);


Code:

      $select = $this->_db->select(); // @var $select Zend_Db_Select
      $select
      ->from('workgroup', array(
         'id'=>'wkg_id', 
         'ident'=>'wkg_code', 
         'name'=>'wkg_label'))
      ->where('wkg_id > :_param');
      $select->setFetchMode(Zend_Db::FETCH_OBJ);
      $statment = $select->query(array('_param' => 5));

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages