Crear un CRUD o ABM con Zend Framework
Por zsamer en Noviembre 24, 2008
En este artículo veremos como agregar/eliminar/modificar datos de una base de datos utilizando Zend_Db_Table.
En informática CRUD es el acrónimo de Crear, Obtener, Actualizar y Borrar (Create, Read, Update y Delete en inglés). Es usado para referirse a las funciones básicas en bases de datos o la capa de persistencia en un sistema de software. En algunos lugares, se utilizan las siglas ABM para lo mismo (Alta Baja Modificación), obviando la operación de Obtener. A veces se nombra ABML siendo la ultima letra (L) de listar, listado o lectura, etc.
Crear una Tabla
Vamos a utilizar MySQL, así que las sentencias SQL para crear la tabla son:
-
CREATE TABLE album (
-
id int(11) NOT NULL AUTO_INCREMENT,
-
artist varchar(100) NOT NULL,
-
title varchar(100) NOT NULL,
-
PRIMARY KEY (id)
-
)
Utiliza esta sentencia en un cliente MySQL como phpAdmin o mediante la línea de comandos de MySQL.
Agregar estos Álbumes.
Vamos a insertar unos registros a la tabla, para realizar pruebas de la funcionalidad de acceso a la información desde la pagina inicial (home). Vamos a tomar los primeros los CD’s del “Hot 100” de Amazon.co.uk:
-
INSERT INTO album (artist, title) VALUES ('James Morrison', 'Undiscovered'),
-
('Snow Patrol', 'Eyes Open');
El Modelo (model)
Zend_Db_Table es una clase abstracta, así que debemos de proporcionar una descripción específica para gestionar álbumes. No importa como llamemos a nuestra clase, pero es de sentido común asignarle el nombre de la tabla de la base de datos. Así que nuestra clase se llamara Album ya que nuestra tabla se llama album. Se le va indicar el nombre de la tabla a Zend_Db_Table para que la gestione, debemos de proteger el nombre de la tabla utilizando la propiedad $_name. Zend_Db_Table asume que la tabla tiene una llave primaria que tiene habilitada la opción de auto-increment. El nombre de este campo puede ser modificado si así se desea.
Vamos a guardar la clase Album en el directorio de models:
quickstart/application/models/Album.php
-
<?php
-
class Album extends Zend_Db_Table
-
{
-
protected $_name = 'album';
-
}
Afortunadamente para nosotros los requisitos son sencillos, ya Zend_Db_Table resuelve toda la funcionalidad que necesitamos. Sin embargo si necesitas agregar mayor funcionalidad a model, entonces este es el lugar adecuado para ponerlo. Por lo general, alguna de las funcionalidades extras será específica de los métodos de búsqueda para encontrar algún tipo de dato que se requiera. También podemos pedirle información relacionada de varias tablas a Zend_Db_Table para que encuentre los datos solicitados.
Nuestra clase modelo extiende a la clase Zend_Db_Table_Abstract, esta última implementa un conocido patrón de diseño llamadoTable Data Gateway y Row Data Gateway
Listado de los Álbumes
Ahora que hemos inicializado la configuración y la información de la base de datos, podemos entrar de lleno al código de la aplicación y mostrar el listado de los CD’s. La clase controladora que se encargará de realizar esta tarea será la clase AlbumController. Está muy claro que cada acción (action) dentro del AlbumController estará manipulando la base de datos de album por medio de la clase Album, así que cargaremos la clase album cuando inicializamos el controlador (controller). A través del método init():
quickstart /application/controllers/AlbumController.php
-
class AlbumController extends Zend_Controller_Action
-
{
-
/**
-
* FlashMessenger
-
*
-
* @var Zend_Controller_Action_Helper_FlashMessenger
-
*/
-
protected $_flashMessenger = null;
-
-
public function init()
-
{
-
$this->initView();
-
$this->_flashMessenger = $this->_helper->FlashMessenger;
-
$this->view->baseUrl = $this->_request->getBaseUrl();
-
$this->view->messages = $this->_flashMessenger;
-
Zend_Loader::loadClass('Album');
-
}
-
}
Esto es un ejemplo de una implementación de Zend_Loader::loadClass() para cargar nuestras propias clases, funciona correctamente porque hemos incluido la ruta de nuestro directorio de models dentro del archivo index.php.
Vamos a mostrar la lista de nuestros álbumes en una tabla dentro de indexAction():
quickstart /application/controllers/AlbumController.php
-
/*...*/
-
public function indexAction()
-
{
-
$this->view->title = "Listado de Albums";
-
$album = new Album();
-
$this->view->albums = $album->fetchAll();
-
}
-
/*...*/
La función Zend_Db_Table::fetchAll() nos regresa un Zend_Db_Table_Rowset que nos permitirá interactuar con los registros plasmados en el template de nuestro archivo view:
quickstart /application/views/scripts/album/index.phtml
-
<?php endif;?>
-
<p><a href="<?php echo $this->baseUrl; ?>/album/add">Nuevo Album</a></p>
-
<table>
-
<tr>
-
<th>Título</th>
-
<th>Artista</th>
-
<th> </th>
-
</tr>
-
<?php foreach($this->albums as $album) : ?>
-
<tr>
-
<td>
-
<a href="<?php echo $this->baseUrl; ?>/album/edit/id/<?php echo $album->id;?>">Editar</a>
-
<a href="<?php echo $this->baseUrl; ?>/album/delete/id/<?php echo $album->id;?>" onclick="return confirm('¿Está seguro que desea eliminar album <?php echo $this->escape($album->title);?>?')">Eliminar</a>
-
</td>
-
</tr>
-
<?php endforeach; ?>
-
</table>
Si nos dirigimos a esta dirección http://localhost/quickstart/public/album (o cualquier ruta que hayan decidido) debe de mostrarnos una lista de dos álbumes.
Agregar nuevos Álbumes
Ahora podemos ver la funcionalidad para agregar nuevos álbumes. Lo cual se puede dividir en dos partes:
1. Mostrar al usuario un formulario con los detalles.
2. Procesar el envió del formulario y almacenar la información en la base de datos.
Todo esto se realiza dentro de addAction():
quickstart/application/controllers/AlbumController.php
-
/*...*/
-
-
public function addAction()
-
{
-
$this->view->title = "Agregar nuevo Album";
-
$form = $this->_getForm();
-
$form->setAction($this->view->baseUrl . '/album/add');
-
-
if($this->getRequest()->isPost()) {
-
$formData = $this->_request->getPost();
-
if (!$form->isValid($formData)) {
-
$this->view->form = $form;
-
$form->populate($formData);
-
return $this->render('form');
-
}
-
-
try {
-
$albumModel = new Album();
-
$album = $albumModel->createRow();
-
$album->artist = $form->getValue('artist');
-
$album->title = $form->getValue('title');
-
$album->save();
-
$this->_flashMessenger->addMessage('Album ha sido guardado con éxito');
-
$this->_redirect('/album/');
-
} catch (Exception $e) {
-
$this->_flashMessenger->addMessage($e->getMessage());
-
}
-
}
-
-
$this->view->form = $form;
-
$this->render('form');
-
}
-
-
private function _getForm()
-
{
-
$form = new Zend_Form();
-
$form->setMethod('post');
-
-
// Crear y configurar el elemento artist:
-
$artist = $form->createElement('text', 'artist');
-
$artist->setLabel('Artista')
-
->addValidator(new Zend_Validate_Alnum(true))
-
->setRequired(true);
-
-
// Crear y configurar el elemento title:
-
$title = $form->createElement('text', 'title');
-
$title->setLabel('Título')
-
->addValidator(new Zend_Validate_Alnum(true))
-
->setRequired(true);
-
-
// Agregar los elementos al form:
-
$form->addElement($artist)
-
->addElement($title)
-
-
return $form;
-
}
-
/*...*/
Hay que observar cómo se analiza la variable $_SERVER['REQUEST_METHOD'] para verificar que el formulario haya sido enviado. Si se ha enviado, obtenemos el objeto formulario con su los validadores y filtros correspondiente, para asegurarnos que ningún código HTML sea permitido. Después asumimos que se han llenado los campos correspondientes, hacemos uso de la clase Album(), para registrarlos en la base de datos. Después de agregar el nuevo registro, los redirigimos a la raíz de la aplicación con el método _redirect().
Para finalizar configuramos el view con el template adecuado para la forma. Adelantándonos un poco, podemos visualizar que la forma edit action será similar a esta, por eso utilizaremos un mismo template (form.phtml) que será llamado desde la acción add y edit:
La vista para agregar un álbum:
quickstart/application/views/scripts/album/form.phtml
Modificar un Álbum
Modificar un álbum es casi idéntico que agregarlo, así que el código es similar:
quickstart /application/controllers/AlbumController.php
-
/*...*/
-
public function editAction()
-
{
-
$id = (int)$this->_request->getParam('id', 0);
-
$this->view->title = "Editar Album";
-
$form = $this->_getForm();
-
$form->setAction($this->view->baseUrl . '/album/edit/id/' . $id);
-
-
$albumModel = new Album();
-
$album = $albumModel->find($id)->current();
-
-
if (null === $album) {
-
$this->_flashMessenger->addMessage('Este Album no existe');
-
$this->_redirect('/album');
-
}
-
-
if ($this->_request->isPost())
-
{
-
$formData = $this->_request->getPost();
-
if (!$form->isValid($formData)) {
-
$this->view->form = $form;
-
$form->populate($formData);
-
return $this->render('form');
-
}
-
-
try {
-
$album->artist = $form->getValue('artist');
-
$album->title = $form->getValue('title');
-
$album->save();
-
$this->_flashMessenger->addMessage('Album ha sido guardado con éxito');
-
$this->_redirect('/album/');
-
} catch (Exception $e) {
-
$this->_flashMessenger->addMessage($e->getMessage());
-
}
-
}
-
-
$this->view->album = $album;
-
$form->populate($this->view->album->toArray());
-
$this->view->form = $form;
-
$this->render('form');
-
}
-
/*...*/
Utiliza la misma vista que la acción add. form.phtml
Eliminar un Album
Para terminar nuestra aplicación debemos de añadir la eliminación de registros. Tenemos un enlace “Delete” junto a cada registro de nuestra lista, sería muy ingenuo de nuestra parte si se eliminara al hacer click en dicho enlace. Esto sería erróneo. Si recordamos las especificaciones HTML, podemos recordar que no debemos llevar a cabo una acción irreversible con GET sin antes confirmar por seguridad. Debemos mostrar una forma de confirmación cuando el usuario realice clic en “Delete” y después presionan el botón de “Aceptar”, llevamos a cabo la eliminación. El código se asemeja al action de “edit” y “add”:
quickstart /application/controllers/AlbumController.php
-
/*...*/
-
public function deleteAction()
-
{
-
$id = (int)$this->_request->getParam('id', 0);
-
-
$albumModel = new Album();
-
$album = $albumModel->find($id)->current();
-
-
if (null !== $album) {
-
try {
-
$album->delete();
-
$this->_flashMessenger->addMessage('Album ha sido borrado con éxito');
-
} catch (Exception $e) {
-
$this->_flashMessenger->addMessage($e->getMessage());
-
}
-
} else{
-
$this->_flashMessenger->addMessage('Este Album no existe');
-
}
-
-
$this->_redirect('/album');
-
}
-
/*...*/
Hay que hacer nota, que hacemos un “redirect” después de ejecutar la eliminación del objeto. Esto se hace con fin de poder redirigirnos de vuelta al listado de los álbumes al final de la función. Además verifica que el objeto fue encontrado en la base de datos antes de ejecutar su eliminación.
Espero que haya sido de utilidad.
![]()
Comentarios
32 Responses to “Crear un CRUD o ABM con Zend Framework”
Deja tu comentario

Magnifico tutorial! (como todos), además se puede encajar con el que hiciste hace poco de tu clase Grid. Muy buen trabajo!
¿Qué utilizas para mostrar el código en los tutoriales de forma tan clara?
Gracias y hasta pronto.
Gracias Daniel, así es, para mi es un gusto compartir y trato de hacer lo mejor posible.
Muy bueno como siempre negro.
Lastima que seguis usando metodos que no son action en el controller
Crear un Crud,o Abm con Zend Framework…
Una guia como crear un modulo para alta baja modificaciones, y listado de datos….
Pablo no entendí: “Lastima que seguis usando metodos que no son action en el controller.” ¿Por qué?
Quien dice que no se pueda o no sea buenas prácticas. Las mejores practicas lo hacen, solo basta ver los ejemplos de la propio Zend en su quickstart, Magento lo hace a menudo en sus controladores.
Controller es una clase más que implementa cierta interfaz y debe tener los métodos que sea necesario para su función ya sean action o no, como por ejemplo _upload, _save o alguna operación repetitiva de lógica de negocio, para reutilizar código.
En el caso del formulario también hay otra opción quizás sea la mejor, pero es más larga y ampliaría el tutorial, lo que no sería lo optimo. Esta otra opción es crear nuestro propio form que herede del Zend_Form y en el metodo init() hacer toda la operación para crear el formulario, pero insisto no era el caso de este tutorial.
Si nos remontamos a otros framework como spring de java que tiene una implementación MVC muy parecida a la de ZF en muchos ejemplos sus controladores tienen métodos que no son necesariamente action.
Hola Zsamer,
¿Cómo haces para presentar el código en tu blog? Quiero decir, con los números, colores y cada función con su link al manual de php. ?Usas algún script? Te estaría muy agradecido si me lo dijeras.
Gracias y hasta pronto.
@zsamer: Me parece mucho mas limpio que un controller, solo contengan los Action, que de hecho es la funcion de la C en MVC, el mismo codigo que estas usando ahi deberia ser un Helper. Pero puede ser manias mias. Con un helper es bastante claro, pero obviamente te va a llevar mas lineas en este post.
@Daniel: http://www.deanlee.cn/wordpress/code_highlighter_plugin_for_wordpress/
Daniel, yo uso el plugins de wordpress: wp plugins gsyntax-hiliter.
saludos.
Excelente tutorial, mucho mejor en español.
Saludos
Me ha gustado mucho como ha mantenido todos los tutoriales basado en un solo proyecto “quickstar”
Saludos
Pablo: podrias hacer un tutorial de la forma en que dices?, por que me he quedado con esa duda sobre “no son Action”, necesitaria un ejemplo vivo para saber de que hablas, pues tenia pensado que http://controller/action/parametro era como funcionaba la cosa….
Saludo
No es por nada…. jejeje el mensaje de confirmacion con JS … exactamente de donde sale?
En la documentacion de ZendF, en que parte puedo leer al respecto?
Saludos
Nota: cuando trato de eliminar un registro, me da error sobre “que no se encontro el delete.phtml”, pero igual crearlo no cuesta nada.
Saludos
mmm hice el detele.phtml , pero hay un problema, al borrar el registro me lleva al delete.phtml y tengo que darle refresh para que vuelva al listado de albumnes….
Algo suelto?
Saludos
Asinox, debería de funcionar tal como esta en tutorial, si no te redirige después de eliminar debes de tener algún problema. Puede ser que tengas alguna salida html antes del _redirect, o alguna otra cosa.
En todo caso prueba con los siguiente:
Al final del método deleteAction agrega exit();
Ej:
$this->_redirect(’/album’);
exit();
Creo que me perdi de algo, pero no sé si en algun lado habian creado el controller Album…por que aqui en este Post no esta, pero igual todo esta bien, solo he cambiado las referencias al controlador album por indexController, ya que tengo este tutorial en ese controller…todo bien, solo queria aclarar que no vi en ningun lado donde se creaba el controlador Album…
En cuanto al error al eliminar…pues copie el codigo tuyo sobre el que habia escrito yo mirandolo…y perfecto
Gracias, con este Post en verdad he empezado a comprender ZF mucho mejor…este post me ayudo mucho, ahora entiendo mucho mejor un libro que tengo.
Saludos
Asinox, tienes toda la razón se me fué ese detalle, donde en realidad la clase Controladora (Controller) debería ser AlbumController y no indexController. Ya lo arreglé.
O bien como dices que sea indexController y modificar los redirect al index:
$this->_redirect(’/index’);
@Asinox: ya estoy haciendo un tutorial, no con tanta calidad y prolijidad como los de Zsamer, pero estoy en eso.
Gracias a ambos
Pablo, pues es que me interesa ver eso tambien…
Saludos
Muy bueno el tutorial, una consulta, estoy empezando con ZF, y no entiendo bien como se puede ‘acomodar’ el render de un zend_form, es decir, ubicacion de campos y botones use display groups pero no entiendo de fondo como acomodar los elementos del form con flexibilidad.
Espero me entiendan
Saludos
Por defecto los elementos se ordenan por orden de ingreso al objeto form, además se puede configurar el orden con el método setOrder del objeto elemento.
Para más te aconsejo que leas el manual oficial ahí se explica bien detallado.
saludos.
muy bueno!
[...] buen ejemplo de como crear un CRUD con Zend Framework lo tenemos en el blog de Zsamer. Lo primero que tenemos que hacer es configurar la conexion a la base de datos, los datos de esta [...]
[...] Crear un CRUD o ABM con Zend Framework [...]
Holas Zsamer talves ya dejastes este blog o este post por ser antiguo pero por fis necesito una ayuda mira que he estado haciendo el CRUD pero no me resulta nada al momento de hacer as actualiaciones es decir le doy a update y me retorna uno le doy a save de la forma en que lo planteas en el blog pero tambien solo me retorna 1 este es mi codigo
$personaModel = new PersonaModel ( );
// $where = $personaModel->getAdapter ()->quoteInto ( 'id_persona', $id );
try {
// print_r($valuesForm);
$persona = $personaModel->find($id)->current(); //array('id_persona'=>$id));
print_r($persona->id_persona);
$persona->nombres=$valuesForm['nombres'];
$persona->apellido_paterno = $valuesForm['apellido_apterno'];
$persona->apellido_materno = $valuesForm['apellido_materno'];
$persona->telefono = $valuesForm['telefono'];
$persona->save();
echo “Los datos de la persona se modificaron correctamente”;
} catch ( Exception $error ) {
echo “error al guardar los datos” + $error;
}
donde $valuesForm son los valores que me llegan desde el formulario, ha estoy enviando los datos via ajax y la respuesta tambien con json y jquery
plis te estare agradecido por la ayuda
Hola zsamer
Me preguntaba por que ZF, no tiene un generador de admin automatico, asi como synfony o django.Ya que esto me ahorraria un monton de tiempo.
Si alguien lo ha creado y tuvieras conocimiento de ello, me podrias enviar alguna referencia para buscarlo y analizarlo
Si no fue creado, crees que seria bueno implementar uno y cual seria el grado de complejidad para crearlo osea que tan dificil seria el implementarlo.
De antemano Gracias por tu respuesta
hola intente probar la primer parte solo la de ver la lista de albumnes y me arroja el siguiente error.
Fatal error: Call to a member function getMessages() on a non-object in F:\wamp\www\Biblioteca\application\views\scripts\index\index.phtml on line 1
sabes que puede ser? gracias
saludos
interesante el tutorial, pero no me parace tam limpio el codigo , comparando con los framework que se usan para hacer aplicaiones java … unn
hola… estoy empezando con zend… estoy un poco confundida con la estructura q se hace porq por lo visto en el controlador se colocan los botones y las cajas texto aqui no estamos cumpliendo con el MVC.. alguien m pueden explicar como funciona esto…??? xq estoy intentando hacer un formulario pero estoy confundida por esto.. por fa el q pueda ayudarm c lo agradeceria..
Muchisimas gracias por estos excelentes aportes. Hace poco me interese en aprender a trabajar con este framework y la verdad es el primer sitio que encuentro con información realmente util (en español). De nuevo muchas gracias por todo el tiempo que dedicas.
Buenos dias.. tengo una duda, no entiendo dond sabe el boton cual es su accion… se que en el controlador esta esto ‘/album/edit/id/’ y m imagino q es cuando el sabe cual funcion va a ejecutar…?? pero sigo sin entender porq en album no existen esas funciones ellas estan en el controlador.. si alguien m puede ayudar c lo agradeceria!!
Hola Caro, te invito a que tomes el próximo curso de Zend, ahí aprenderás todo como enfrentar un proyecto con Zend Framework. El costo es bastante accesible.
Si te interesa puedes registrarte en este link:
Registro Curso Zend
Gracias pero pense q m podia ayudar… Gracias!!!