Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
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
$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.
/** * @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
$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
/** * @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
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
$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
$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
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
je regarderais ça mais il y a une incohérence c'est sur
Hors ligne
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
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
$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);
où
$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