Por favor, haz un clic sobre los anuncios cuando pases por mi blog, ya? =)

Zend Framework 3: Estructura del proyecto

12 comentarios
Este artículo es la tercera parte de mi  tutorial de Zend Framework. La segunda parte está acá.

La estructura del proyecto recién creado se ve así:


Un poco confuso ¿no? Mas no colapses aún, intrépido programador, que es sencillo de entender.
Antes de seguir, asegurémonos de que nuestro servidor web está configurado para  usar ZF.

Configuración de Apache (mod_rewrite)
Para que ZF funcione, todas las urls deben ser procesadas por el archivo index.php, el cual decidirá qué hacer con ellas. Por ejemplo, si yo escribo
http://localhost/miproyecto/public/
http://localhost/miproyecto/public/algo/otro
http://localhost/miproyecto/public/saludo/hola

todas esas páginas deberían redirigirse a
http://localhost/miproyecto/public/index.php , el cual decidirá qué paginas mostrar, según la url que se le envíe.

Para que esto se pueda hacer, en el archivo de configuración de apache, httpd.conf :
G:\xampp\xampp\apache\conf\httpd.conf

Debemos descomentar esto:
LoadModule rewrite_module modules/mod_rewrite.so

y reiniciar apache.

 Ahora, probaremos nuestro proyecto recién creado en el artículo anterior. Debemos inciar Apache ( si estamos usando Xampp, podemos hacerlo desde el Xampp Control Panel)

Una vez que estamos seguros de que mod_rewrite está activado, abramos nuestro navegador favorito y escribamos la direccion:
http://localhost/miproyecto/public/

y veremos esto:


¡ Felicidades!. Nuestro proyecto en ZF está creado con éxito.

Ahora echaremos un vistazo en los archivos, carpetas y el resto de la estructura de ZF.


Como habíamos dicho, esta es la estructura de carpetas del proyecto:


 Veamos el archivo index.php, ubicado en la carpeta public
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

/** 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();

Lo explicaremos por partes:

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
indica que la carpeta en donde estarán las clases PHP que implementan el modelo MVC estarán dentro de la carpeta /../application


 
// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? 
getenv('APPLICATION_ENV') : 'production'));
indica que nuestro sistema al funcionar ocupará la configuración guardada en la sección 'production'. Como veremos muy pronto, hay otras secciones más como 'development' y 'testing' que pueden tener otros valores. Por ejemplo, el indicar si se deben mostrar o no los mensajes de error.

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
Indica que nuestras clases y librerías de php que coloquemos en la carpeta /../library serán incluidas en el include_path del sistema.

/** 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();

crea un objeto  Zend_Application según la configuración indicada en el archivo '/configs/application.ini' y lo echa a correr. Este objeto es el que hace la redireccion de las urls, inicializa las demás clases, las carga, etc.

Ahora examinemos el archivo /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"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1 

Este archivo permite indicar el valor de algunas variables de entorno del sistema. Como el objeto  Zend_Application lee este archivo al iniciarse, podemos modificar algunos valores en este archivo y así ahorrarnos el tocar el código en PHP.

En este archivo tenemos tres secciones (aunque nosotros podriamos agregar más):

  • [production]
  • [staging : production] (que hereda todas las variables desde production, y los agrega o modifica)
  • [testing : production] (que hereda todas las variables desde production, y los agrega o modifica)
  • [development : production] (que hereda todas las variables desde production, y los agrega o modifica)

Por ejemplo, como development hereda las variables de la sección de producción, esta contendría:

phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 1

Pero a la vez modifica el valor de las variables
phpSettings.display_startup_errors,
phpSettings.display_errors,
resources.frontController.params.displayExceptions

para que muestren los errores. ¿Qué significa esto? Que si estamos corriendo el sistema en ambiente de production no veremos errores de codigo o de coneccion  en la pantalla, pero si lo corremos en ambiente de development, veremos el trazado de errores indicando el nombre de la clase en que ocurrió el error, el código que falló, etc.

Ahora, cómo le decimos al sistema en qué ambiente debe funcionar, produciotn, testing o development? Simple, volvamos al archivo index.php en la carpeta public a las líneas 8 y 9:

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ?
getenv('APPLICATION_ENV') : 'production'));

si cambiáramos production por development, entonces nuestro sistema mostraría los errores y funcionaría con la configuración de development. Esto hace más fácil el desarrollo, pues podemos tener distintas configuraciones para distintos ambientes en una forma sencilla.

También en el archivo  application.ini podemos indicar los parámetros de la o las bases de datos a las que deseamos acceder, entre muchas otras cosas. Más de esto después.

Ahora sigamos viendo los demás archivos.

application/Boostrap.php

Este archivo nos sirve para inicializar las clases del modelo MVC y llamar a algunas funciones que queremos que se llamen para todas ellas

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{


}

Como pueden ver no viene con nada, pero nosotros podríamos agregarle un código  como este:

protected function _initView() 
{ 
  $view = new Zend_View(); 
  $view->setEncoding('UTF-8'); 
  $view->doctype('XHTML1_STRICT'); 
  $view->headMeta()->appendHttpEquiv( 
                       'Content-Type', 'text/html;charset=utf-8' 
  ); 
  $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper( 
                 'ViewRenderer' 
  ); 
  $viewRenderer->setView($view); 
  return $view; 
} 
El cual, dicho en forma simple, indica que todas las paginas creadas en este proyecto serán de codificación  XHTML1_STRICT, con conjunto de caracteres  utf-8.

Existen muchas otras clases y métodos que se pueden configurar en este archivo, pero como este es un tutorial sencillo, no daremos más ejemplos.


Manejo de Controladores y Vistas

Como dijimos al principio, ZF implementa el modelo MVC, donde las clases del Modelo son las que acceden a las tablas de las bases de datos, las de la Vista son las páginas con HTML y las del Controlador son las que controlan (valga la redundancia) a las dos anteriores.

Dentro de ZF, un Controlador es una Clase y las vistas son creadas por métodos de esta clase, llamados Acciones.
La url indica el controlador y la acción a la que se llama. Por ejemplo, si colocamos en el navegador:

http://localhost/miproyecto/public/album/agregar
entonces en nuestro proyecto deberemos tener una clase controlador llamada Album, que tenga un método llamado agregar, que cree una página web llamada agregar.phtml

http://localhost/miproyecto/public/album/index
entonces en nuestro proyecto deberemos tener una clase controlador  llamada Album, que tenga un método llamado index, que cree una página web llamada index.phtml

http://localhost/miproyecto/public/album/borrar
entonces en nuestro proyecto deberemos tener una clase controlador  llamada Album, que tenga un método llamado borrar, que cree una página web llamada borrar.phtml

Aquí se muestra el código de la clase mencionada:

class AlbumController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
    }
    //accion agregar
    public function agregarAction()
    {
        // desde aquí coloco datos al archivo 
    // agregar.phtml, que es el que se mostrará al final
    }
    //accion index
    public function indexAction()
    {
         // desde aquí coloco datos al archivo 
    // index.phtml, que es el que se mostrará al final
    }

    //accion borrar
    public function borrarAction()
    {
         // desde aquí coloco datos al archivo 
    // borrar.phtml, que es el que se mostrará al final
    }
}

Al crear un proyecto en ZF se crea automáticamente un controlador llamado Index, con la accion llamada index, que son las que se llaman por defecto, si es que o se indica nombre de controlador ni accion:
Por eso, cuando hacemos

http://localhost/miproyecto/public
http://localhost/miproyecto/public/index
http://localhost/miproyecto/public/index/index
llamamos al controlador index, accion index()

Dónde está la clase controladora index? Podemos verla en
/application/controllers/IndexController.php

Tocas las clases controladoras tienen el nombre de la forma NombreclaseController.php
Si abrimos la clase /application/controllers/IndexController.php, veremos que dentro contiene la función indexAction(), que es la que se llama cuando hacemos
http://localhost/miproyecto/public/index/index

o alguna de las de más arriba

class IndexController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        // action body
    }
}

Ahora, cómo creamos una nueva acción y nuevas clases controladoras? Lee el siguiente artículo.

12 comentarios :

Travianero dijo...

Estudiado y entendido ;)

Manuel dijo...

Muy bien explicado todo y de gran utilidad.

Gracias

Unknown dijo...

Hola buenas tardes
todo muy bien claro ;)
excelente tutorial
algo así buscaba por inet
hasta que lo encontré, pero sabes lo malo es que tengo dramas con el direccionamiento en las URL =/
ya que al ingresar las direcciones

http://localhost/miproyecto/public/index

http://localhost/miproyecto/public/index/index

me sale un mensaje de error.
y en el archivo

httpd.conf tengo descomentado la línea
LoadModule rewrite_module modules/mod_rewrite.so

pero aun así no me funciona
en cambio al ingresar

http://localhost/proyecto1/public/index.php/index

tome bien y sale la imagen del index.php

pero esa no es la idea =/

di me pudieras ayudar porfavor ;)

Unknown dijo...

Encontré la solución =D
Buscando por inet llegue a una pagina que estaba en portugués >.<
pero con la ayuda del traductor google, lo pude hacer :p
es bien sencillo, y lo dejare por si a alguien más le sucede...
el caso es que yo estoy usando ZendSever ya que la instalación
es mucho más sencilla no hay que configurar nada y todo una vez instalado funciona Ok!
el CLI y la Integración con Netbeans
a excepción del problema de direccionamiento ¬¬
en el archivo httpd.conf de apache
hay que sustituir esta línea AllowOverride None (si usas ZendServer está en la línea 212)
por AllowOverride All
reiniciar Apache y funciona :)

Anónimo dijo...

Hola buenas, hace meses segui este tutorial y tube éxito en todo, pero ahora trabajando y montando el sitio en un hosting, tengo el primer problema, no funciona el redireccionamineto de los controladores, esto es devido a que el hosting y la mayoría casi todos no tienen activado el mod_rewrite en apache y la unica solución según ellos es crear un php.ini..? pero eso no tiene nada que ver con htttp.conf....?
ahora tengo problemas con la entrega de un proyecto, por este tema, si me pudieras ayudar, te lo agradeceria muchisimo

Angelorum dijo...

Hola, para que zend funcione el hosting DEBE tener activado el mod_rewrite.
De otra forma, no s epodra hacer la redireccion al controlador correspondiente.

Crear un php.ini no tiene nada que ver.

Saludos

G dijo...

Muchas gracias!! son pocos los aportes como el tuyo en cuanto a tutoriales de ZF... he encontrado cosas que no se explican en otros lados y me dejan mucho mas claro algunos conceptos... Gracias nuevamente y mucha suerte!!

Sigfrido dijo...

Hola. Muy bueno el tutorial, muchas gracias. Solo una corrección. Cambia "Tocas" por "Todas" en el ultimo parrafo.

Un saludo

Anónimo dijo...

Hola q tal!
Todo claro hasta el momento; sin embargo, en la última parte: la clase IndexController tiene una función indexAction(); esta función no tiene cuerpo, la anterior, tampoco. Entonces, como llama a index.php contenido en la carpeta public?
Espero que me responda alguién que haya entendido esa aprte. Gracias!

lillium dijo...
Este comentario ha sido eliminado por el autor.
lillium dijo...

a mi me sale un error
404 no found cuando ejecuto el proyecto ¿que hago?

Anónimo dijo...

Gracias.. me esta sirviendo mucho, hasta hora todo bien y aprendiendo. Nuevamente gracias por el aporte..