ZEND

RECU-0261 (Recurso Referencia)

Descripción

Zend Framework (ZF) es un framework de código abierto para desarrollar aplicaciones web y servicios web con PHP5. ZF es una implementación que usa código 100% orientado a objetos. La estructura de los componentes de ZF es algo único; cada componente está construido con una baja dependencia de otros componentes. Esta arquitectura débilmente acoplada permite a los desarrolladores utilizar los componentes por separado. A menudo se refiere a este tipo de diseño como "use-at-will" (uso a voluntad).

Aunque se pueden utilizar de forma individual, los componentes de la biblioteca estándar de Zend Framework conforman un potente y extensible framework de aplicaciones web al combinarse. ZF ofrece un gran rendimiento y una robusta implementación MVC, una abstracción de base de datos fácil de usar, y un componente de formularios que implementa la prestación de formularios HTML, validación y filtrado para que los desarrolladores puedan consolidar todas las operaciones usando de una manera sencilla la interfaz orientada a objetos.

Introducción

A continuación se van a listar las principales características funcionales que ofrece el framework

  • Trabaja con MVC (Model View Controller)
  • Cuenta con módulos para manejar archivos PDF, canales RSS, Web Services (Amazon, Flickr, Yahoo), etc
  • El Marco de Zend también incluye objetos de las diferentes bases de datos, por lo que es extremadamente simple realizar consultas a la base de datos, sin tener que escribir ninguna consulta SQL.
  • Una solución para el acceso a base de datos que balancea el ORM con eficiencia y simplicidad.
  • Completa documentación y tests de alta calidad para realizar testing.
  • Soporte avanzado para i18n (internacionalización).
  • Un buscador compatible con Lucene.
  • Implementa clases prar facilitar la autenticación y filtrado de entrada.
  • Clientes para servicios web, incluidos Google Data APIs y StrikeIron.
  • Muchas otras clases útiles para hacerlo tan productivo como sea posible

Listas de control de acceso

Zend_Acl provee la implementación de un sistema simple y flexible de Listas de Control de Acceso (ACL, por sus siglas en inglés) para la administración de privilegios. En general, una aplicación puede utilizar las ACL para controlar el acceso a ciertos objetos protegidos, que son requeridos por otros objetos. Para los propósitos de esta documentación:

  • Un recurso es un objeto al cual el acceso esta controlado.
  • Un rol es un objeto que puede solicitar acceso a un recurso.

En términos generales, los roles solicitan acceso a los recursos . Por ejemplo, si una persona solicita acceso a un automóvil, entonces la persona se convierte en el rol solicitante, y el automóvil en el recurso, puesto que el acceso al automóvil puede no estar disponible a cualquiera. A través de la especificación y uso de Listas de Control de Acceso (ACL), una aplicación puede controlar cómo los objetos solicitantes (roles) han obtenido acceso a objetos protegidos (recursos).

Acerca de los Recursos

En Zend_Acl, crear un recurso es muy sencillo. Zend_Acl proporciona el Zend_Acl_Resource_Interface para facilitar a los desarrolladores la creación de recursos. Una clase solo necesita implementar su interfaz, la cual consiste en un método único, getResourceId() , para que Zend_Acl considere el objeto como un recurso. Adicionalmente, Zend_Acl_Resource es proporcionado por Zend_Acl como un recurso básico de aplicación para que los desarrolladores puedan extenderla hasta donde lo deseen. Zend_Acl provee un estructura de árbol a la cual pueden ser agregados múltiples recursos (o "Áreas con Controles de Acceso").Ya que los recursos son almacenados en esta estructura de árbol, estos pueden ser organizados desde lo general (hacia la raíz del árbol) a lo específico (hacia las ramas del árbol).

Las Consultas sobre un recurso específico buscarán automáticamente, en la jerarquía del recurso, reglas asignadas a recursos anteriores a los que el recurso actual haga referencia, permitiendo la herencia simple de reglas. Por ejemplo, si una regla por defecto se aplica a cada edificio en una ciudad, uno simplemente podría asignar la regla a la ciudad, en lugar de asignar la misma regla a cada edificio. Algunos edificios pueden necesitar excepciones a la regla, sin embargo, y esto es fácil de hacer en Zend_Acl asignando esta excepción a cada edificio que necesite una excepción a la regla. Un recurso sólo puede heredar de un recurso padre, aunque este recurso padre puede tener a la vez su propio recurso padre, y así; sucesivamente. Zend_Acl también soporta privilegios sobre recursos (ejemplo. "crear","leer","actualizar", "borrar"), y el desarrollador puede asignar reglas que afecten o a todos los privilegios o a privilegios específicos sobre un recurso.

Acerca de las Reglas

Al igual que los recursos, la creación de un rol también es muy simple. Zend_Acl proporciona Zend_Acl_Role_Interface para facilitar a los desarrolladores la creación de roles. Una clase solo necesita la implementación de su interfaz, la cual consiste en un método único, getRoleId() , para que Zend_Acl considere que el objeto es un Rol. Adicionalmente, Zend_Acl_Role está incluido con Zend_Acl como una implementación principal del rol para que los desarrolladores la extiendan hasta donde lo deseen.

En Zend_Acl, un Rol puede heredar de otro o más roles. Esto es para soportar herencia de reglas entre roles. Por ejemplo, un Rol de usuario, como "sally", puede estar bajo uno o más roles padre, como "editor" y "administrador". El desarrollador puede asignar reglas a "editor" y "administrador" por separado, y "sally" puede heredar tales reglas de ambos, sin tener que asignar reglas directamente a "sally".

Creando las Listas de Control de Acceso (ACL)

Una ACL puede representar cualquier grupo de objetos físicos o virtuales que desee. Para propósitos de demostración, sin embargo, crearemos un ACL básico para un Sistema de Administración de Contenido (CMS) que mantendrá varias escalas de grupos sobre una amplia variedad de áreas. Para crear un nuevo objeto ACL, iniciamos la ACL sin parámetros:

require_once 'Zend/Acl.php';
$acl = new Zend_Acl();

Registrando roles

El Sistema de Administración de Contenido (CMS) casi siempre necesita una jerarquía de permisos para determinar la capacidad de identificación de sus usuarios. Puede haber un grupo de 'Invitados' para permitir acceso limitado para demostraciones, un grupo de 'Personal' para la mayoría de usuarios del CMS quienes realizan la mayor parte de operaciones del día a día, un grupo 'Editores' para las responsabilidades de publicación, revisión, archivo y eliminación de contenido, y finalmente un grupo 'Administradores' cuyas tareas pueden incluir todas las de los otros grupos y también el mantenimiento de la información delicada, manejo de usuarios, configuración de los datos básicos y su respaldo/exportación. Este grupo de permisos pueden ser representados en un registro de roles, permitiendo a cada grupo heredar los privilegios de los grupos 'padre', al igual que proporcionando distintos privilegios solo para su grupo individual.

Instrucciones require_once

Lazy loading es una técnica de optimización diseñada para impulsar la operación de hacer la carga de un archivo de clase esperando hasta el último momento (es decir, cuando se instancia un objeto de esa clase, se llama a un método de clase estático, o hacen referencia a una propiedad de clase constante o estática). PHP soporta la carga automática a través de este tipo, que le permite definir uno o más callbacks para ejecutar con el fin de asignar un nombre de clase en un archivo.

Sin embargo, la mayoría de los beneficios que puede obtener de carga automática se eliminan si el código de la biblioteca sigue realizando llamadas del tipo require_once () (que es precisamente el caso de Zend Framework). Entonces, la pregunta es ¿cómo se puede eliminar esas llamadas require_once () a fin de maximizar el rendimiento del cargador automático?

Una manera simple de reducir las llamadas require_once() es utilizar las utilidades Unix en conjunción con comentar las llamadas. Un ejemplo:

% cd path/to/ZendFramework/library
      % find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
        -not -wholename '*/Application.php' -print0 | \
        xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'

Este código, de una sola línea (separado en dos líneas para facilitar su lectura), recorre en iteración cada archivo PHP y reemplaza cada instancia de "require_once" por "/ / require_once ', comentando cada uno. (Se mantienen las llamadas a require_once () dentro de Zend_Application y Zend_Loader_Autoloader, ya que en estas clases se producirá un error sin ellos.)

Este comando puede ser añadido a una construcción automatizada o liberar el proceso trivial, ayudando a mejorar el rendimiento en su aplicación de producción. Cabe señalar, sin embargo, que si utiliza esta técnica, debe utilizar la carga automática, puede hacerlo desde su archivo "public/index.php" con el siguiente código:

require_once 'Zend/Loader/Autoloader.php';
      Zend_Loader_Autoloader::getInstance();

Carga de plugins

Muchos componentes tienen plugins que permiten crear sus propias clases para utilizar el componente, incluso sobrescribiendo las existentes en el marco. Esto proporciona flexibilidad importante al marco pero a un precio: el proceso de cargar el plugin es una tarea bastante costosa.

El cargador de plugin permite registrar el par prefijo_clase y path, permitiéndole especificar el fichero de clases en paths no estandars. Cada prefijo puede tener asociado varios path. Internamente, el cargador de plugins engancha cada prefijo, adjuntando cada path y comprobando que existe el fichero y está en modo lectura en ese path. Entonces lo carga, comprobando que la clase que buscaba está disponible. Como puede imaginar, esto provoca un número muy elevado de llamadas al sistema

Si multiplicamos esto por el número de componentes que llaman al PluginLoader, nos podemos hacer una idea de la importancia de mejorarlo. Estos son algunos de los componentes que hacen uso del Plugin loader.

  • Zend_Controller_Action_HelperBroker: helpers
  • Zend_Dojo: view helpers, elementos de formularios y decoradores
  • Zend_File_Transfer: adaptadores
  • Zend_Filter_Inflector: filtros
  • Zend_Filter_Input: filters and validators
  • Zend_Form: validadores, filtros, elementos, captcha
  • Zend_Paginator: adaptadores
  • Zend_View: helpers, filtros
Para reducir el numero de llamadas se usa la cache de archivos que incluye PluginLoader. Aunque esta funcionalidad crea llamadas a " include_once()" en el código, también asegura que los beneficios de utilizar PluginLoader se obtienen lo antes posible.

Consultas complejas

Zend_Db_Select es relativamente bueno en su trabajo. Sin embargo, si va a realizar consultas complejas, que requieren joins o sub-selecciones, a menudo puede ser bastante ingenuo. Se puede mejorar su uso.

La única respuesta real es escribir su propio SQL; Zend_Db no requiere el uso de Zend_Db_Select, por lo que proporcionar su propia sintaxis de declaraciones. Select SQL es un método perfectamente legítimo, ejecutar EXPLAIN en sus consultas, y probar una variedad de enfoques de forma fiable hasta que se puedan obtener su índices con mayor rendimiento (y luego codificar el SQL como una propiedad de clase o constante).

Si el SQL requiere argumentos variables, proporcione marcadores de posición en el SQL, y utilice una combinación de vsprintf () y array_walk () para inyectar los valores en el código SQL:

// $adapter is the DB adapter. In Zend_Db_Table, retrieve
// it using $this->getAdapter().
$sql = vsprintf(
self::SELECT_FOO,
array_walk($values, array($adapter, 'quoteInto'))
      );

Para aquellos que usan vistas parciales pesadas, se vuelve evidente que el partial() view helper incurre en un montón de gastos generales, debido a la necesidad de clonar el objeto de vista. Para mejorar esta situación, partial() sólo se usará cuando realmente sea justificado. El partial() view helper acepta tres argumentos:

  • $name: nombre de la vista a renderizar
  • $module: nombre del modulo donde reside la vista
  • $model: un array o objeto a pasar a la representación parcial para limpiar los datos a asignar a la vista.

El poder de usar partial() proviene del segundo y tercer argumento. El argumento $module permite a partial() añadir el nombre del módulo donde reside la vista para que el script de vista parciales se resuelva en ese módulo; el argumento $model permite pasar variables explícitas para usarlas con la vista parcial. 

Inicialización por defecto

Zend_Application facilita la inicialización de nuestras aplicaciones proporcionando recursos reutilizables, comunes y asociados con el módulo de la clase de arranque y control de dependencias. También se ocupa de establecer el entorno de PHP e introduce la autocarga (autoloading) por defecto.

Obtener una aplicación MVC configurada y lista para funcionar requiere de un porcentaje cada vez mayor de código que disponga de más características, tales como: Establecer la base de datos, configurar la vista y los ayudantes(helpers) de vistas, configurar los layouts, registro de plugins, registro de ayudantes de acción (action helpers), y mucho más.

Además, a menudo deseará reutilizar el mismo código para arrancar sus pruebas, un cronjob, o un servicio en linea de comandos. Si bien es posible incluir simplemente su script bootstrap, a menudo hay inicializaciones que son específicas del entorno, puede que no necesite el MVC para un cronjob, o simplemente la capa de DB para un servicio script. Zend_Application pretende hacer esto más fácil y promover la reutilización mediante el encapsulamiento del bootstraping en paradigmas de OOP. Zend_Application está dividida en tres áreas:

  • Zend_Application: carga el entono de PHP, incluyendo include_paths y autocarga, e instancia la clase requerida de bootstrap.
  • Zend_Application_Bootstrap: suministra interfaces para las clases bootstrap. Zend_Application_Bootstrap_Bootstrap ofrece funcionalidad común para la mayoría de las necesidades de bootstrap, incluyendo algoritmos de comprobación de dependencias y la capacidad de cargar recursos de bootstrap por demanda.
  • Zend_Application_Resource provee una interfaz para recursos estandar de bootstrap que pueden ser cargados por demanda mediante una instancia bootstrap, así como implementaciones de varios recursos por defecto.

Los desarrolladores crean una clase de arranque(bootstrap) para sus aplicaciones, extendiendo Zend_Application_Bootstrap_Bootstrap o implementando (mínimamente) Zend_Application_Bootstrap_Bootstrapper. El punto de entrada (por ejemplo, public/index.php) cargará Zend_Application, y la instanciará pasando por:

  • El entorno actual
  • Opciones para bootstrapping

Las opciones de bootstrap incluyen la ruta hacia el archivo que contiene la clase bootstrap y opcionalmente:

  • Cualquier include_paths extras a establecer
  • Cualquier otro namespace de autocarga adicional a registrar
  • Cualquier configuración de php.ini a inicializar
  • El nombre de clase para la clase bootstrap (si no es "Bootstrap")
  • Pares de recursos prefijo de ruta a usar
  • Cualquier recurso a usar (por nombre de clase o nombre corto)
  • Ruta adicional al archivo de configuración a cargar
  • Opciones adicionales de configuración

Las opciones pueden ser un array, un objeto Zend_Config, o la ruta a un archivo de configuración.

Autenticación y Autorización

Zend_Auth provee una API para autenticación e incluye adaptadores concretos de autenticación para escenarios de casos de uso común. Zend_Auth es concerniente sólo con autenticación y no con autorización . Autenticación es vagamente definido como:

  • Determinar si una entidad realmente es lo que pretende ser (o sea, identificación), basándose en un grupo de credenciales.
  • Autorización, el proceso de decidir si se permite a una entidad: acceso a, o el realizar operaciones en, otras entidades esta fuera del alcance de Zend_Auth .

Adaptadores

Un adaptador Zend_Auth es usado para autenticar en contra de un tipo particular de servicio de autenticación, como LDAP, RDBMS, o almacenamiento basado en ficheros. Diferentes adaptadores pueden tener opciones y comportamientos muy diferentes, pero algunas cosas básicas son comunes entre los adaptadores de autenticación. Por ejemplo, aceptar credenciales de autenticación (incluyendo una identidad supuesta), realizar consultas ante el servicio de autenticación, y regresar resultados, son comunes para los adaptadores Zend_Auth.

Cada clase adaptadora Zend_Auth implementa Zend_Auth_Adapter_Interface . Esta interface define un metodo, authenticate() , que la clase adaptadora debe implementar para realizar una petición de autenticación. Cada clase adaptadora debe ser preparada antes de llamar a authenticate() . Esta preparación del adaptador incluye la creación de credenciales (p.ej. nombre de usuario y contraseña) y la definición de valores para opciones de configuración específicos del adaptador, como valores de conexión a base de datos para un adaptador de tabla de base de datos.

El siguiente ejemplo es un adaptador de autenticación que requiere que un nombre de usuario y contraseña sean especificados para la autenticación. Otros detalles, como la forma de realizar peticiones al servicio de autenticación, han sido omitidos por brevedad:

class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
   /**
   * Establece nombre de usuario y contraseña para autenticacón
   *
   * @return void
   */
   public function __construct($username, $password)
   {
    // ...
   }
   /**
   * Realiza un intento de autenticación
   *
   * @throws Zend_Auth_Adapter_Exception Si la autenticación no puede
   * ser realizada
   * @return Zend_Auth_Result
   */
   public function authenticate()
   {
   // ...
   }
}

Los adaptadores Zend_Auth regresan una instancia de Zend_Auth_Result con authenticate() para representar el resultado de un intento de autenticación. Los adaptadores llenan el objeto Zend_Auth_Result en cuanto se construye, así que los siguientes cuatro métodos proveen un grupo básico de operaciones "frente al usuario" que son comunes a los resultados de adaptadores Zend_Auth:

  • isValid() - regresa true si y solo si el resultado representa un intento de autenticación exitoso
  • getCode() - regresa una constante identificadora Zend_Auth_Result para determinar el tipo de fallo en la autenticación o si ha sido exitosa. Este puede ser usado en situaciones cuando el desarrollador desea distinguir entre varios tipos de resultados de autenticación. Esto permite a los desarrolladores, por ejemplo, mantener estadísticas detalladas de los resultados de autenticación. Otro uso de esta característica es: proporcionar al usuario mensajes específicos detallados por razones de usabilidad, aunque los desarrolladores son exhortados a considerar el riesgo de proporcionar tales detalles a los usuarios, en vez de un mensaje general de fallo en la autenticación. Para más información, vea las siguientes notas:
  • getIdentity() - regresa la identidad del intento de autenticación
  • getMessages() - regresa un arreglo de mensajes pertinentes a un fallido intento de autenticación

Tabla de base de datos de autenticación

Zend_Auth_Adapter_DbTable proporciona la capacidad de autenticar contra credenciales almacenadas en una tabla de la base de datos. Como Zend_Auth_Adapter_DbTable requiere una instancia de Zend_Db_Adapter_Abstract que será pasada a su constructor, cada instancia está vinculada a una conexión concreta de la base de datos. Se pueden establecer otras opciones de configuración a través del constructor y de métodos de instancia. Las opciones de configuración disponibles incluyen:

  • tableName: Nombre de tabla de la base de datos que contiene las credenciales de autenticación, y contra la cual se realiza la búsqueda de autenticación en la base de datos.
  • identityColumn: Nombre de la columna de la tabla de la base de datos utilizada para representar la identidad. La columna identidad debe contar con valores únicos, tales como un apellido ó una dirección de e-mail.
  • credentialColumn: Nombre de la columna de la tabla de la base de datos utilizada para representar la credencial. Conforme a un sistema de identidad simple y autenticación de contraseña, el valor de la credencial corresponde con la contraseña. Véase también la opción credentialTreatment .
  • credentialTreatment: En muchos casos, contraseñas y otros datos son encriptados, mezclados, codificados, ocultados, desplazados o tratados de otra manera a través de alguna función o algoritmo. Al especificar una cadena de tratamiento parametrizada con este método, tal como 'MD5(?)' o 'PASSWORD(?)', un desarrollador podría aplicar sentencias arbitrarias SQL sobre los datos credenciales de entrada. Ya que estas funciones son específicas de los RDBMS, debemos consultar el manual de la base de datos para comprobar la disponibilidad de tales funciones para su sistema de base de datos.

Cache

Zend_Cache provee una forma genérica para cualquier caché de datos. El almacenamiento en caché en Zend Framework se opera por interfaces, mientras que los registros de caché son almacenados a través de adapatadores del backend ( Archivo , Sqlite , Memcache ...) mediante un sistema flexible de documentos de identidad y etiquetas. Utilizando éstas, es fácil en el futuro eliminar determinados tipos de registro. (Ejemplo: "eliminar todos los registros caché de determinada etiqueta"). El módulo principal (Zend_Cache_Core) es genérico, flexible y configurable. Aun para sus necesidades específicas existen frontends de caché que extienden Zend_Cache_Core a conveniencia: Output , File , Function y Class

Existen diversos frontend dentro del framework. A continuación vamos a revisarlos brevemente:

  • Zend_Cache_Core es un frontend especial porque es el núcleo del modulo. Es un cahce generico y extiende a otras clases.
  • Zend_Cache_Frontend_Output es un frontend dedicado a las captura de la salida. Utiliza el buffer de salida para capturar todo desde el método start() hasta que llega el método end()
  • Zend_Cache_Frontend_Function los resultados de las funciones llamadas. Tiene un método simple de nombre call() que captura el nombre de la función y los parámetros necesarios para la llamada en un array
  • Zend_Cache_Frontend_File dedicado a cachera ficheros maestros.
  • Zend_Cache_Frontend_Page esta diseñadao para capturar la página completa. No se puede utilizar Zend_Cache_Frontend_Page para cachear solo un bloque

Obtener un frontend con Zend_Cache::factory()

Zend_Cache::factory() ejemplifica objetos correctos y los une. En este primer ejemplo, usaremos el frontend Core junto con el backend File .

$frontendOptions = array(
 'lifetime' => 7200, // tiempo de vida de caché de 2 horas
 'automatic_serialization' => true
 );
$backendOptions = array(
 'cache_dir' => './tmp/' // Carpeta donde alojar los archivos de caché
 );
// getting a Zend_Cache_Core object
$cache = Zend_Cache::factory('Core',
                             'File',
                              $frontendOptions,
                              $backendOptions);

Modelo Vista Controlador

Zend_Controller es el corazón del sistema de MVC de Zend Framework MVC. Zend_Controller_Front implementa el patrón Front Controller (Controlador Frontal) en el cual todas las transacciones HTTP (requests) son interceptadas por el controlador frontal y enviado a una Acción particular de un Controlador según la URL pedida.

El sistema Zend_Controller fue construido con la extensibilidad en mente, ya sea heredando las clases existentes, escribiendo nuevas clases que implementan varias interfaces o clases abstractas que forman la base de la familia de clases del controlador, o escribiendo plugins o helpers de las acciones para aumentar o manipular la funcionalidad del sistema.

zend.controller.basics.png

El flujo de procesos de Zend_Controller está implementado por varios componentes. Si bien no es necesario entender los cimientos de todos estos componentes para utilizar el sistema, tener un conocimiento práctico del proceso es de mucha utilidad.

  • Zend_Controller_Front organiza todo el flujo de trabajo del sistema Zend_Controller. Es una interpretación del patrón FrontController. Zend_Controller_Front procesa todas las solicitudes recibidas por el servidor y es responsable en última instancia de la delegación de las solicitudes a los ActionControllers (Zend_Controller_Action).
  • Zend_Controller_Request_Abstract (a menudo denominado Request Object) representa el entorno de la solicitud y ofrece métodos para establecer y recuperar el controlador, los nombres de las acciones y cualquier parámetro de solicitud. Además realiza un seguimiento de si la acción que contiene ha sido enviada o no por Zend_Controller_Dispatcher. Se pueden usar extensiones del objeto abstracto para encapsular toda el entorno de la solicitud, permitiendo a los routers traer información del ámbito de la solicitud a fin de establecer el controlador y los nombres de acción. Por defecto, se usa Zend_Controller_Request_Http, el cual proporciona acceso a todo el ámbito de la petición HTTP.
  • Zend_Controller_Router_Interface se usa para definir routers. El ruteo es el proceso de examinar el ámbito de la solicitud para determinar qué controlador, y qué acción del controlador debe recibir la solicitud. Este controlador, la acción, y los parámetros opcionales son luego establecidos en el objeto de la solicitud para ser procesados por Zend_Controller_Dispatcher_Standard. El ruteo (routing) ocurre sólo una vez: cuando la solicitud se recibe inicialmente y antes de enviar el primer controlador. El router por defecto, Zend_Controller_Router_Rewrite, toma el punto final de una URI como se especificó en Zend_Controller_Request_Http y la descompone en un controlador, una acción y parámetros, basándose en la información de la ruta del url. Como ejemplo, la URL "http://localhost/foo/bar/key/value" se decodificará para usar el controlador foo, la acción bar y especificar un parámetro key con el valor de value. Zend_Controller_Router_Rewrite también puede ser utilizado para igualar las rutas arbitrarios; para más información, ver documentación del router.
  • Zend_Controller_Dispatcher_Interface se usa para definir dispatchers. Dispatching (Despachar) es el proceso de sacar el controlador y la acción del objeto que solicita y mapearlo a un controlador archivo/clase y al método acción en la clase del controlador. Si el controlador o acción no existen, hará un manejo para determinar los controladores por defecto y las acciones a enviar. El proceso actual de dispatching(despacho) consta de instanciar la clase del controlador y llamar al método acción en esa clase. A diferencia del routing, que ocurre sólo una vez, el dispatching(despacho) ocurre en un bucle. Si el estado del objeto que que envía la solicita es reseteado en cualquier punto, el bucle se repetirá, llamando a cualquier acción que esté actualmente establecida en la solicitud del objeto. La primera vez el bucle termina con la solicitud del objeto, el estado de lo enviado se establece a (booleano true), que terminará el procesamiento.
  • Zend_Controller_Action es el componente base del controlador de acción. Cada controlador es una sola clase que extiende la clase Zend_Controller_Action y debe contener uno o más métodos de acción.
  • Zend_Controller_Response_Abstract define una clase base de respuesta utilizada para recoger y retornar respuestas de los controladores de acción. Recoge tanto a las cabeceras como al contenido del cuerpo. La clase de respuesta (response) por defecto es Zend_Controller_Response_Http, la cual es adecuada para usarla en un entorno HTTP.

El flujo de procesos de Zend_Controller es relativamente sencillo. Una solicitud es recibida por Zend_Controller_Front, la que a su vez llama a Zend_Controller_Router_Rewrite para determinar qué controlador (y la acción en ese controlador) despachar. Zend_Controller_Router_Rewrite descompone la URI a fin de establecer el controlador y el nombre de acción en la solicitud. Zend_Controller_Front entonces entra al bucle del dispatch. Llama a Zend_Controller_Dispatcher_Standard, el que pasa la solicitud para enviar al controlador y a la acción especificada en la solicitud (o el usado por defecto). Después de que el controlador ha terminado, el control vuelve a Zend_Controller_Front. Si el controlador ha indicado que debe enviarse otro controlador mediante el reinicio del estado de la condición de la solicitud, el bucle continúa y se ejecuta otro envio. En caso contrario el proceso termina

El Front Controller

Zend_Controller_Front implementa una instancia del patrón Front Controller usado en aplicaciones Model-View-Controller (MVC). Su propósito es inicializar el entorno de la solicitud, rutear la solicitud entrante, y luego hacer un envío de cualquiera de las acciones descubiertas; le agrega las respuestas y las devuelve cuando se completa el proceso.

Zend_Controller_Front también implementa el patrón Singleton , significando que solo una única instancia de él puede estar disponible en cualquier momento dado. Esto le permite actuar también como un registro en el que los demás objetos pueden extraer del proceso dispatch.

Zend_Controller_Front registra un plugin broker consigo mismo, permitiendo que diversos eventos que dispara sean observados por plugins. En muchos casos, esto da al desarrollador la oportunidad de adaptar el proceso de dispatch al sitio sin la necesidad de ampliar el Front Controller para añadir funcionalidad.

Como mínimo, el front controller necesita uno o más paths a directorios que contengan action controllers a fin de hacer su trabajo. Una variedad de métodos también pueden ser invocados para seguir adaptando el medio ambiente del front controller y ese a sus clases Helper.

La solicitud del Objeto

El objeto request es un objeto de valor simple que es pasado entre Zend_Controller_Front y el router, dispatcher, y clases de controlador. Empaqueta los nombres del módulo solicitado, controlador, acción, y los parámetros opcionales, así como el resto del entorno de la solicitud, ya sea HTTP, el CLI, o PHP-GTK.

  • El nombre del módulo es accedido por getModuleName() y setModuleName().
  • El nombre del controlador es accedido por getControllerName() y setControllerName().
  • El nombre de la acción que llamar dentro del controlador es accedido por getActionName() y setActionName().
  • Los parámetros accesibles por la acción son un array asociativo de pares clave/valor que son recuperados por getParams() y configurados con setParams(), o configurados individualmente por getParam() y setParam().

Basado en el tipo de solicitud, puede haber más métodos disponibles. La solicitud por defecto usada, Zend_Controller_Request_Http, por ejemplo, tiene métodos para recuperar la URI de la solicitud,la ruta de la información, parámetros $_GET y $_POST, etc. El objeto request es pasado al controlador front, o si no es provisto, es instanciado al principio del proceso dispatcher, antes de que ocurra el enrutamiento. Es pasado a través de todos los objetos en la cadena del dispatcher. Adicionalmente, la solicitud objeto es particularmente útil en pruebas. El desarrolador puede cambiar el entorno de la solicitud, incluyendo módulos, controladores, acciones, parámetros, URI, etc, y pasar la solicitud objeto al controlador front para probar el flujo de la aplicación. Cuando se vincula con el objeto respuesta , es posible elaborar y precisar una unidad de pruebas de aplicaciones MVC.

El Router Standard

Zend_Controller_Router_Rewrite Es el router standard del Framework. Routing es el proceso de tomar la parte final de una URI (la parte de la URI que viene después de la URL base) y la descomposición en parámetros para determinar qué módulo, qué controlador y acción de ese controlador debe recibir la solicitud. Estos valores del módulo,controlador, acción y otros parámetros están enpaquetados en un objeto Zend_Controller_Request_Http el cual es procesado luego por Zend_Controller_Dispatcher_Standard. El routing ocurre sólo una vez: cuando se recibió inicialmente la solicitud y antes del dispatch del primer controlador. Zend_Controller_Router_Rewrite está diseñado para permitir que una funcionalidad tipo mod_rewrite se pueda usar en estructuras PHP puras. Se basa muy vagamente en el routing de Ruby on Rails (RoR) y no requiere ningún conocimiento previo de reescritura de la URL del webserver. Está diseñado para trabajar con solo una regla mod_rewrite de Apache

El Despachador

Despachar es el proceso de tomar el objeto solicitud, Zend_Controller_Request_Abstract, extraer el nombre del módulo, el nombre del controlador, el nombre de la acción, y los parámetros opcionales contenido en él, y luego instanciar un controlador y llamar una acción de ese controlador. Si no se encuentra algún módulo, controlador o acción, se usarán los valores por defecto para ellos. Zend_Controller_Dispatcher_Standard especifica index para cada uno de los controladores y acciones por defecto y default para el valor por defecto del módulo, pero permite al desarrollador cambiar los valores por defecto para cada uno usando los métodos setDefaultController(), setDefaultAction(), y setDefaultModule() respectivamente.

El proceso de despachar tiene lugar en un bucle en el front controller. Antes de llevarse a cabo el despacho, el front controller rutea la solicitud para encontrar valores especificados por el usuario para el módulo, controlador, acción, y los parámetros opcionales. A continuación entra en un loop de despacho, despachando la solicitud. Al comienzo de cada iteración, establece un flag en el objeto solicitud indicando que la acción se ha despachado. Si una acción o un plugin pre/postDispatch resetea ese flag, el loop de despacho continuará e intentará despachar la nueva solicitud. Cambiando el controlador y/o la acción en la solicitud y reseteando el flag despachado, el desarrollador puede definir una cadena de peticiones a realizar. El método del controlador de acción que controla ese despacho es _forward(); llamar a este método para cualquiera de los pre/postDispatch() o métodos de acción, proporcionando un controlador de acciónes, módulo y, opcionalmente cualquier parámetro adicional que desee enviar a la nueva acción:

public function fooAction()
{
     // adelantar a otra acción en el controlador y módulo actuales:
     $this->_forward('bar', null, null, array('baz' => 'bogus'));
}
public function barAction()
{
     // adelantar a una acción en otro controlador:
     // FooController::bazAction(),
     // en el módulo actual:
     $this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}
public function bazAction()
{
     // adelantar a una acción en otro controlador en otro módulo,
     // Foo_BarController::bazAction():
     $this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}

Controladores de Acción

Zend_Controller_Action es una clase abstracta que puede utilizar para implementar controladores de acción (Action Controllers) para usar con el Front Controller al crear un un sitio basado en el patrón Modelo-Vista-Controlador (MVC).

Para usar Zend_Controller_Action, necesitará hacerla una subclase en sus clases actuales de controladores de acción (o hacerla una subclase para crear su propia clase base de acción de controladores). La operación más elemental es hacerla una subclase, y crear métodos de acción que corresponden a las diversas acciones que desee que el contralor maneje para su sitio. El manejo del ruteo y envío de Zend_Controller descubrirá por sí mismo cualquier método que termine en 'Action' en su clase, como posibles acciones del controlador. Por ejemplo, digamos que su clase se define como sigue:

class FooController extends Zend_Controller_Action
{
   public function barAction()
   {
   // hacer algo
   }
   public function bazAction()
   {
   // hacer algo
   }
}

Action Helpers

Los Action Helpers permiten a los desarrolladores inyectar funcionalidad ent iempo de ejecución a cualquier Controlador de Acción que extienda a Zend_Controller_Action. Action Helpers minimizan la necesidad de extender la abstracción de Action Controller en el orden de inyectar funcionalidades comunes.

Hay muchas maneras de utilizar los Action Helpers. Action Helpers employ the use of a brokerage system, similar to the types of brokerage you see in Zend_View_Helper, and that of Zend_Controller_Plugin. Action Helpers (like Zend_View_Helper) may be loaded and called on demand, or they may be instantiated at request time (bootstrap) or action controller creation time (init()).

Emplean el uso de un sistema de corretaje, similar a los tipos de intermediación que ves en Zend_View_Helper, y de Zend_Controller_Plugin. Action Helpers(como Zend_View_Helper) se pueden cargar en demanda, o pueden crear una instancia en el momento de solicitud (arranque) o en el tiempo de la creacion del controlador de acción (init ()).

Enlaces externos

Contenidos relacionados