lastInsertId() avec Zend_Db_Table_Abstract
CrazyCat » 17/ 02/2010 17:47
PHP
|
Envoyer à un ami |
Fil des commentaires de ce billet
En suivant le tutoriel Zend QuickStart, je me suis retrouvé confronté à un problème: aucun accès au dernier id créé.
C'est une lacune connue mais pas encore corrigée. Voici la méthode que j'ai utilisée pour y remédier:
Nouvel abstract
Dans le répertoire applications/models/Db, création de la classe Default_Model_Db_Abstract qui étend la classe d'origine Zend_Db_Table_Abstract :
<?php abstract class Default_Model_Db_Abstract extends Zend_Db_Table_Abstract { /** * Last insert id. * * @access private * @var int */ private $_iLastInsertId = 0; /** * returns last insert id. * * @access private * @return int */ private function getLastInsertId() { return $this->_iLastInsertId; } /** * Initialisation * * @access public * @return void */ public function init() { } /** * Override the initial insert function * * @access public * @param array $aData * @return mixed */ public function insert(array $aData) { $mReturn = parent::insert($aData); $this->setLastInsertId($this->getAdapter()->lastInsertId()); return $mReturn; } /** * Returns the last insertId * * @access public * @return int */ public function lastInsertId() { if (! $this->getLastInsertId()) { throw new Exception('Retrieving last insert ID is meaningless without inserting before.'); } return $this->getLastInsertId(); } /** * Sets the last insert ID * * @access private * @param int $iLastInsertId * @return Db_Table_Abstract */ private function setLastInsertId($iLastInsertId) { $this->_iLastInsertId = $iLastInsertId; return $this; } }
Modèles de tables
Les modèles contenus dans applications/models/DbTable/ sont ensuite de la forme:
<?php class Default_Model_DbTable_Users extends Default_Model_Db_Abstract { protected $_name = 'users'; }
Mapper
Au niveau du mapper (applications/models/UsersMapper.php), la fonction setDbTable() est modifiée ainsi:
public function setDbTable($dbTable) { if (is_string($dbTable)) { $dbTable = new $dbTable(); } if (!$dbTable instanceof Default_Model_Db_Abstract) { throw new Exception('Invalide table data gateway provided'); } $this->_dbTable = $dbTable; return $this; }
Avec ceci, partout dans le mapper on a accès à $this->getDbTable->lastInsertId(), comme c'était possible en passant par l'ancien adaptateur.
Commentaires
Le 18/ 03/2010 11:23
Bonjour,
Merci pour ce billet, je me creusais la tête pour le même problème, et je ne voyais pas comment m'en sortir ! D'autant plus que j'aurai eu du mal à écrire moi-même ce code... J'essaye d'utiliser les mappers de Zend, comme indiqué dans le quickstart, mais j'ai l'impression que cela complique le code pour pas grand-chose au final, j'ai du mal à en saisir l'utilité. Surtout que le reste de la doc utilise les adapter, donc ça complique l'apprentissage et le debbugage !
Pour le code de la classe Default_Model_Db_Abstract, je n'arrivais pas à récupérer l'id donc je l'ai modifié ainsi :
private function setLastInsertId($lastInsertId) {
$this->_lastInsertId = $lastInsertId;
return $this->_lastInsertId;
}
public function insert(array $aData) {
$mReturn = parent::insert($aData);
return $this->setLastInsertId($this->getAdapter()->lastInsertId());
}
(désolé je n'arrive pas à faire la mise en page pour les méthodes)
Je retourne uniquement la valeur de l'id plutôt que l'objet, je ne sais pas ce qui est le mieux mais c'est la seule façon qui me renvoie bien l'id (le code du billet me fonctionne pas chez moi, je ne sais pas trop d'où cela vient).
Encore merci pour l'aide en tout cas :)