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.