Bootstrapping con Zend Application
Por zsamer en Agosto 30, 2009
Zend_Tool es una poderosa herramienta de Zend Framework que nos permite crear la estructura base de un proyecto Zend con todos sus directorios y componentes, como así también aprovechar un diseño estándar de proyecto y una primer clase de arranque (bootstrap) diseñada por los propios creadores del framework, ubicación para los archivos de configuración, diferenciación de entornos de ejecución (producción, desarrollo, etc), y muchos detalles más.
Crear nuestro proyecto base
Haremos un ejemplo basado en un sistema operativo como GNU/Linux, aunque esto bien se puede hacer también desde Windows a través de un .bat.
Dentro de nuestro web root, en Linux utilizando xampp: /opt/lampp/htdocs/
-
$ mkdir /opt/lampp/htdocs/proyecto-zf
-
$ cd /opt/lampp/htdocs/proyecto-zf
-
$ zf create project .
-
Creating project at /opt/lampp/htdocs/proyecto-zf
Luego nos creará una estructura inicial para nuestro proyecto:
-
nuevo-proyecto-zf
-
|-- application
-
| |-- Bootstrap.php
-
| |-- configs
-
| | `-- application.ini
-
| |-- controllers
-
| | |-- ErrorController.php
-
| | `-- IndexController.php
-
| |-- models
-
| `-- views
-
| |-- helpers
-
| `-- scripts
-
| |-- error
-
| | `-- error.phtml
-
| `-- index
-
| `-- index.phtml
-
|-- library
-
|-- public
-
| `-- index.php
-
`-- tests
-
|-- application
-
| `-- bootstrap.php
-
|-- library
-
| `-- bootstrap.php
-
`-- phpunit.xml
De la estructura generada podemos observar lo siguiente:
Primero que todo, tenemos al directorio public. Este no solo guarda nuestro index.php quien se encarga de arrancar nuestra aplicación, sino que además contiene archivo de imágenes, hojas de estilos css, javascript etc.
Luego tenemos el directorio library, lugar donde guardamos nuestros propios componentes o librerías y las de Zend.
Después vemos que tenemos la carpeta tests, lugar donde llevaremos a cabo nuestras “pruebas unitarias” (testing). Esto puede ser usado generalmente para probar los modelos que deben contener la lógica de negocio y nuestros controladores.
Por último pero no menos importante es el directorio de la aplicación “application”. Este es considerado como el más importante, ya que es donde creamos y guardamos nuestra aplicación MVC, los controladores, modelo, vistas (script o plantillas y view helper) y archivos de configuración.
Se generó un directorio para nuestros archivos de configuración llamado configs, donde a su vez podemos ver un archivo application.ini que cuenta con los primeros parámetros que podemos definir en nuestra aplicación (entorno de producción, desarrollo, testing, si iniciar con el despliegue de mensajes de error, etc).
Nuestro archivo index.php ubicado dentro del directorio “public” quedaría más o menos con el siguiente contenido:
-
// Define path to application directory
-
-
// Define application environment
-
: 'production'));
-
-
// Typically, you will also want to add your library/ directory
-
// to the include_path, particularly if it contains your ZF installed
-
)));
-
-
/** Zend_Application */
-
require_once 'Zend/Application.php';
-
-
// Create application, bootstrap, and run
-
$application = new Zend_Application(
-
APPLICATION_ENV,
-
APPLICATION_PATH . '/configs/application.ini'
-
);
-
$application->bootstrap()
-
->run();
Podemos notar que la constante de ambiente de la aplicación "APPLICATION_ENV" referida al entorno o ambiente en que estemos, tales como de desarrollo, producción o test, esta se puede obtener directamente de la configuración del servidor web Apache, una recomendación puede ser configurarla directamente en el archivo htaccess, dentro del directorio “public”:
-
SetEnv APPLICATION_ENV development
-
-
RewriteEngine On
-
RewriteCond %{REQUEST_FILENAME} -s [OR]
-
RewriteCond %{REQUEST_FILENAME} -l [OR]
-
RewriteCond %{REQUEST_FILENAME} -d
-
RewriteRule ^.*$ - [NC,L]
-
RewriteRule ^.*$ index.php [NC,L]
Adentrándonos en la Estructura de Directorio
Configs
Dentro del directorio configs, encontraremos un archivo llamado “application.ini”. Este archivo se utiliza para definir la configuración base del arranque de nuestro proyecto, el Boostrap. Veremos más adelante cómo podemos agregar recursos a la configuración del arranque, que son auto cargados por la aplicación cuando inicia. Lo fundamental es familiarizarnos con el archivo de configuración y se convertirá en uno de nuestros mejores aliados en ZF.
La configuración por defecto se coloca en “application/configs/application.ini”, y contiene algunas directrices básicas:
-
; application/configs/application.ini
-
-
[production]
-
phpSettings.display_startup_errors = 0
-
phpSettings.display_errors = 0
-
includePaths.library = APPLICATION_PATH "/../library"
-
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
-
bootstrap.class = "Bootstrap"
-
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
-
-
[staging : production]
-
-
[testing : production]
-
phpSettings.display_startup_errors = 1
-
phpSettings.display_errors = 1
-
-
[development : production]
-
phpSettings.display_startup_errors = 1
-
phpSettings.display_errors = 1
Controladores
Dentro del directorio del controlador, se encuentran los archivos para cada controlador. Esto es algo que hemos visto muchas veces, así que no vamos a entrar en detalles. Al llegar a los módulos, no se olvide de anteponer el nombre de módulo, el prefijo, al nombre de clase (es decir, Admin_IndexController).
Modelos
Dentro del directorio de modelos, creamos nuestras clases modelos, un modelo contiene la lógica de negocio, pero no está vinculada a un motor de almacenamiento. Esto significa básicamente que los modelos no son sólo aquellos que extiendan de la clase Zend_Db_Table, sino que también otras fuentes de datos como un archivo plano (CVS), un XML, Web Service, SOAP, alguna fuente de dato proveniente de algún ERP etc.
Vistas
El directorio de las vistas, básicamente nuestras plantillas de presentación XHTML y las clase Helper View.
Añadiendo nuestras librerías
Por ejemplo, supongamos que hemos escrito un par de componentes para procesar archivos planos CVS y otras librerías más (como procesamiento de imágenes con GD) y las llamamos Core (nuestro propio core), entonces las almacenamos dentro del directorio library y en el sub directorio Core. Digamos que queremos añadir estas, sólo tenemos que añadir la siguiente entrada en el application.ini:
-
autoloaderNamespaces.core = "Core_"
-
autoloaderNamespaces.otra = "OtraLibreria_"
-
autoloaderNamespaces.yotramas = "YOtraLibreriaMas_"
Importante: desde nuestra aplicación, se espera que autoloaderNamespaces sea una matriz, razón por la cual necesitamos agregar una clave. Esto significa que podemos agregar múltiples bibliotecas personalizadas. Otro detalle a tener en cuenta es que hay que añadir un guión al final de su prefijo de la biblioteca. Tomando como ejemplo OtraLibreria, este hecho abre la puerta para las clases como OtraLibreria_NombreDeClase).
Agregando módulos
Perfecto, bueno y ¿Esto es todo? No, En realidad no… Como habrán notado, aun no tenemos un directorio de módulos. Así que vamos a cambiar eso y añadiremos nuestro primer módulo, llamado "admin".
-
$zf create module admin
-
Creating the following module and artifacts:
-
…………………..
Como pueden ver, crea un nuevo directorio llamado "modules" dentro del directorio “application”. Ahí se crea el directorio para el módulo "admin" con una estructura similar para el módulo como hemos descrito anteriormente.
Ahora vamos a crear un nuevo controlador para el módulo de modo que tengamos algo que mostrar en admin, quizás un saludo de bienvenida, esto lo hacemos manualmente como siempre lo hacemos.
Ahora, si intentamos en el navegador, ejecutar el módulo admin, vamos a obtener un mensaje de error "Message: Invalid controller specified (admin)".
Entonces, ¿qué hicimos mal? Nada en realidad. Ya que nuestra aplicación aun no está lista. Ya que hemos creado nuestro primer módulo, ahora tenemos que decirle a la configuración “application.ini” que nuestro sistema debe tener la estructura modular de directorio, por lo tanto, vamos a abrir application.ini y agregaremos las siguientes líneas al final del bloque de producción:
-
resources.frontController.moduleDirectory = APPLICATION_PATH "/ modules"
-
resources.modules[] resources.modules []
Ahora estamos en condiciones de ejecutar nuestro módulo en el navegador:
http://localhost/proyecto-zf/public/admin/
El Bootstrap
La clase Bootstrap define que recursos y componentes que se deben inicializar. De forma predeterminada, el Front Controller es inicializado (Zend_Controller_Front), y configura por defecto el directorio “application/controllers/” para manejar los Controladores (Action Controllers).
-
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
-
{
-
}
En la clase Boostraps podemos incluir recursos para que estos sean inicializados cuando arranca la aplicación. Para ello debemos agregar métodos cuyo nombre debe comenzar con el carácter underscore [ _ ] seguido de la palabra init (llamado el prefijo _init) y el nombre del recurso, comenzando este último en mayúscula y caracteres alfanuméricos.
Ejemplo: _initNombreDelRecurso():
Veamos un ejemplo de una estructura típica de una clase Boostrap con Zend_Application:
-
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
-
{
-
protected function _initFoo()
-
{
-
// ...
-
}
-
-
protected function _initBar()
-
{
-
// ...
-
}
-
-
protected function _initBaz()
-
{
-
// ...
-
}
-
}
Para arrancar sólo el método _initFoo (), hacemos lo siguiente:
-
$bootstrap->bootstrap('foo');
Para arrancar los métodos _initFoo () e _initBar (), hacemos lo siguiente:
Para inicializar todos los métodos de los recursos en el arranque, llamaremos a bootstrap() sin argumentos:
-
$bootstrap->bootstrap();
Este último es el más común y es el que observaremos en nuestro archivo de arranque index.php ubicado dentro del directorio “public”.
Veamos un ejemplo más en concreto, ahora agregaremos un recurso para inicializar el objeto vista, el cual queremos poder asignarle el HTML DocType y un valor por defecto al título HTML del sitio.
Esto puede ser implementado editando nuestra clase Bootstrap para agregar el método _initView(), veamos cómo a continuación:
?
-
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
-
{
-
protected function _initView()
-
{
-
// Inicializamos el objeto vista
-
$view = new Zend_View();
-
$view->doctype('XHTML1_STRICT');
-
$view->headTitle('My First Zend Framework Application');
-
-
// Agregamos la vista al ViewRenderer
-
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
-
'ViewRenderer'
-
);
-
$viewRenderer->setView($view);
-
-
// Retornamos siempre el objeto recurso, en este caso la vista
-
// De esta manera el recurso será almacenado dentro del contenedor del Bootstrap
-
return $view;
-
}
-
}
Este método se ejecutará automáticamente cuando se arranque la aplicación, y asegurará que nuestro objeto vista sea inicializado de acuerdo a la necesidad de nuestra aplicación.
De esta manera podríamos tener un método _initXXXX para cada uno de nuestros recursos que queramos inicializar, como por ejemplo:
- _initConfig();
- _initLog();
- _initEnvironment();
- _initLocale();
- _initMail();
- _initConnection();
- _initLayout();
Este tipo de recursos son los llamados personalizados dentro de la clase Bootstrap, por lo tanto somos nosotros quienes tenemos que implementarlo según lo que necesitemos que se inicialice en nuestra aplicación.
?
Luego, para obtener un recurso tenemos que hacerlo de las siguientes formas:
Dentro de la Clase Boostrap
-
$view = $this->getResource('view');
Dentro de Algún Controlador
-
$bootstrap = $this->getInvokeArg('bootstrap');
-
$view = $bootstrap->getResource('view');
Para asegurarnos que el contenedor de Boostrap contiene al recursos, llamamos al método hasResource(string recurso):
-
if ($bootstrap->hasResource('view')) {
-
$view = $bootstrap->getResource('view');
-
}
Ahora tenemos otras formas de agregar recursos y estos ya están implementados implícitamente dentro de Zend_Application (por defecto), es decir ya están disponibles y listos para usar, gracias a Zend Framework, estos son los llamados “Plugins de Recursos Disponibles”.
Para utilizarlos sólo tenemos que configurarlo (activarlo) dentro del archivo de configuración “application.ini” (lo que veremos a continuación).
Plugins de Recursos Disponibles
Resource Layout
Unos de los recursos estándar que nos provee Zend Application es el Recurso de Layout. Para activar este recurso sólo tenemos que configurar de manera adecuada nuestro archivo de configuración “application.ini” definiendo los valores para la instancia del objeto Zend Layout, nombre del layout por defecto y el path:
Entonces dentro de la etiqueta production agregamos lo siguiente:
-
; Agregamos las siguientes lineas:
-
resources.layout.layout = "layout"
-
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
Luego tenemos que crear nuestro archivo de layout dentro de la ruta especificada en la configuración “application/layouts/scripts/” el cual llamaremos layout.phtml:
Resource View
También Zend Application nos provee de un recurso para la vista, solo tenemos que agregar unas líneas en el archivo application.ini como se muestra a continuación:
-
resources.view.encoding = "UTF-8"
-
resources.view.basePath = APPLICATION_PATH "/views/scripts"
Resource Db
Tampoco se podía quedar atrás la inicialización de la conexión a las base de datos.
Zend_Application_Resource_Db inicializará un adaptador Zend_Db basado en las configuraciones asignadas en application.ini. De forma predeterminada, éste también asigna el adaptador por defecto del adaptador que debe utilizar Zend_Db_Table:
-
[production]
-
resources.db.adapter = "pdo_mysql"
-
resources.db.params.host = "localhost"
-
resources.db.params.username = "webuser"
-
resources.db.params.password = "XXXXXXX"
-
resources.db.params.dbname = "test"
-
resources.db.isDefaultTableAdapter = true
Resource Frontcontroller
Probablemente el recurso más importante y común que se carga con Zend_Application será el recurso Front Controller, que nos proporciona la capacidad de configurar Zend_Controller_Front.
Este recurso proporciona la capacidad de establecer parámetros del front controller, especificar los plugins a inicializar, y mucho más.
Una vez inicializado, el recurso asigna la propiedad $frontController del arranque a la instancia Zend_Controller_Front.
-
[production]
-
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
-
resources.frontController.moduleControllerDirectoryName = "actions"
-
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
-
resources.frontController.defaultControllerName = "site"
-
resources.frontController.defaultAction = "home"
-
resources.frontController.defaultModule = "static"
-
resources.frontController.baseUrl = "/subdir"
-
resources.frontController.plugins.foo = "My_Plugin_Foo"
-
resources.frontController.plugins.bar = "My_Plugin_Bar"
-
resources.frontController.env = APPLICATION_ENV
Nos adentramos en el funcionamiento de Zend Application, las funcionalidades que puede involucrar, como así también algunas de las posibilidades para ampliarlo, creando un archivo de configuración o iniciando un sistema de logger con Zend_Log, etc.
Comentarios
7 Responses to “Bootstrapping con Zend Application”
Deja tu comentario

[...] bootstrapping con zend application (Español, muy bien explicado) [...]
Muy buenas,
Hay una cosa que no comprendo en el planteamiento de la estructura de directorios en relacion a una aplicación basada en Modelos-Vistas-Controladores o por el contrario en Módulos.
Ya que aunque efectivamente generas una carpeta para ubicar los módulos (application/modules/), siguen habiendo aún en el directorio anterior (application/) las carpetas “controllers”, “models” y “views”.
¿ No quedan estos directorios un poco fuera de lugar si nos basamos en módulos, o hay razones para que estos sigan estando ahí ? Si las hay, serías tan amable de explicarnoslas aunque sea brevemente ?
Muchas gracias !!
Y Enhorabuena por el blog. ; )
Claro, esa es la estructura básica que se crea, sin duda podemos decirle a Zend Tool que genere la estructura modular donde cada módulo que generemos con la herramienta tendrá los directorios “controllers”, “models” y “views”.
Además nos daremos cuenta en application.ini tendremos la linea que configura la estructura modular:
resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
Pero una vez creas esa estructura modular… ¿ Puedes automáticamente prescindir de esas tres carpetas “controllers”, “modules”, “views” ? La aplicación ya no depende de ellas ?
Cuando vas a configurar application.ini para que admita modulos. El código de ejemplo está mal.
resources.frontController.moduleDirectory = APPLICATION_PATH “/ modules”
resources.modules[] resources.modules []
No funciona. Si lo dejas así. Si.
resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
Me imagino es una errata de copia y pega.
Hola,
He seguido todos los pasos para crear mi proyecto y todo salió bien, pero cuando quiero crear un módulo me sale este error: “An error has ocurred. The project was not found”.
Utilizo xampp y windows vista.
pd: cuando creo el módulo estoy dentro de la carpeta del proyecto creado.
Saludos
[...] Doctrine 2 con Zend Framework, para ello va ser necesario haber leido también el articulo sobre Bootstrapping con Zend Application, que será nuestra base para la [...]