TigerZF
🌐Español

24.4. El objeto Request

24.4.1. Introducción

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

  • Se accede al nombre del módulo mediante getModuleName() y setModuleName().

  • Se accede al nombre del controlador mediante getControllerName() y setControllerName().

  • Se accede al nombre de la acción a llamar dentro de ese controlador mediante getActionName() y setActionName().

  • Los parámetros accesibles por la acción son un array asociativo de pares clave-valor que se obtienen con getParams() y se establecen con setParams(), o individualmente con getParam() y setParam().

Según el tipo de petición, puede haber más métodos disponibles. El request usado por defecto, Zend_Controller_Request_Http, por ejemplo, tiene métodos para obtener el URI de la petición, la información de ruta, los parámetros $_GET y $_POST, etc.

El objeto request se pasa al controlador frontal, o si no se proporciona ninguno, se instancia al comienzo del proceso de despacho, antes de que ocurra el enrutamiento. Se pasa a través de cada objeto en la cadena de despacho.

Adicionalmente, el objeto request es particularmente útil en pruebas. El desarrollador puede fabricar el entorno de la petición, incluyendo módulo, controlador, acción, parámetros, URI, etc, y pasar el objeto request al controlador frontal para probar el flujo de la aplicación. Cuando se combina con el objeto response, se vuelven posibles pruebas unitarias elaboradas y precisas de aplicaciones MVC.

24.4.2. Peticiones HTTP

24.4.2.1. Acceso a los datos de la petición

Zend_Controller_Request_Http encapsula el acceso a valores relevantes como el nombre de clave y el valor para las variables de router del controlador y la acción, y todos los parámetros adicionales analizados desde el URI. Además permite acceder a valores contenidos en las superglobales como miembros públicos, y gestiona la URL base actual y el URI de la petición. No es posible establecer valores de superglobales en un objeto request; en su lugar, utilice los métodos setParam() y getParam() para establecer o recuperar parámetros de usuario.

[Note] Datos de superglobales

Al acceder a los datos de superglobales a través de Zend_Controller_Request_Http como propiedades públicas de miembro, es necesario tener en cuenta que el nombre de la propiedad (clave del array superglobal) se corresponde con una superglobal en un orden de precedencia específico: 1. GET, 2. POST, 3. COOKIE, 4. SERVER, 5. ENV.

Como alternativa, se puede acceder a superglobales específicas utilizando un método público. Por ejemplo, el valor bruto de $_POST['user'] se puede obtener llamando a getPost('user') en el objeto request. Estos incluyen getQuery() para obtener elementos de $_GET, y getHeader() para obtener las cabeceras de la petición.

[Note] Datos GET y POST

Tenga cuidado al acceder a los datos desde el objeto request, ya que no se filtran de ninguna manera. El router y el dispatcher validan y filtran los datos para sus propias tareas, pero dejan los datos intactos en el objeto request.

[Note] Obtención de los datos POST en bruto

Desde la versión 1.5.0, también puede obtener los datos POST en bruto a través del método getRawBody(). Este método devuelve FALSE si no se enviaron datos de esa forma, pero devuelve el cuerpo completo del post en caso contrario.

Esto es útil principalmente para aceptar contenido al desarrollar una aplicación MVC RESTful.

También puede establecer parámetros de usuario en el objeto request usando setParam() y recuperarlos posteriormente usando getParam(). El router utiliza esta funcionalidad para establecer en el objeto request los parámetros encontrados en el URI de la petición.

[Note] getParam() obtiene más que parámetros de usuario

Para realizar parte de su trabajo, getParam() en realidad obtiene datos de varias fuentes. En orden de prioridad, estas incluyen: los parámetros de usuario establecidos mediante setParam(), los parámetros GET, y finalmente los parámetros POST. Tenga esto en cuenta al obtener datos mediante este método.

Si desea obtener solo de los parámetros que estableció mediante setParam(), use getUserParam().

Además, desde la versión 1.5.0, puede restringir qué fuentes de parámetros se consultarán. setParamSources() le permite especificar un array vacío o un array con uno o más de los valores '_GET' o '_POST' indicando qué fuentes de parámetros están permitidas (por defecto, ambas están permitidas); si desea restringir el acceso solo a '_GET' especifique setParamSources(array('_GET')).

[Note] Peculiaridades de Apache

Si está usando el manejador 404 de Apache para pasar las peticiones entrantes al controlador frontal, o usando un flag PT con reglas de reescritura, $_SERVER['REDIRECT_URL'] contiene el URI que necesita, no $_SERVER['REQUEST_URI']. Si está usando una configuración así y obtiene un enrutamiento no válido, debería usar la clase Zend_Controller_Request_Apache404 en lugar de la clase HTTP por defecto para su objeto request:

$request = new Zend_Controller_Request_Apache404();
$front->setRequest($request);

Esta clase extiende la clase Zend_Controller_Request_Http y simplemente modifica la autodetección del URI de la petición. Puede usarse como un reemplazo directo.

24.4.2.2. URL base y subdirectorios

Zend_Controller_Request_Http permite que Zend_Controller_Router_Rewrite se use en subdirectorios. Zend_Controller_Request_Http intentará detectar automáticamente su URL base y establecerla en consecuencia.

Por ejemplo, si mantiene su index.php en un subdirectorio del servidor web llamado /projects/myapp/index.php, la URL base (base de reescritura) debería establecerse en /projects/myapp. Esta cadena se eliminará entonces del inicio de la ruta antes de calcular cualquier coincidencia de ruta. Esto libera de la necesidad de anteponerla a cualquiera de sus rutas. Una ruta 'user/:username' coincidirá con URIs como http://localhost/projects/myapp/user/martel y http://example.com/user/martel.

[Note] La detección de URL distingue mayúsculas de minúsculas

La detección automática de la URL base distingue entre mayúsculas y minúsculas, así que asegúrese de que su URL coincida con el nombre de un subdirectorio en un sistema de archivos (incluso en máquinas Windows). Si no coincide, se lanzará una excepción.

Si la URL base se detecta incorrectamente, puede sobrescribirla con su propia ruta base con la ayuda del método setBaseUrl() de la clase Zend_Controller_Request_Http, o de la clase Zend_Controller_Front. El método más sencillo es establecerla en Zend_Controller_Front, que la trasladará al objeto request. Ejemplo de uso para establecer una URL base personalizada:

/**
 * Dispatch Request with custom base URL with Zend_Controller_Front.
 */
$router     = new Zend_Controller_Router_Rewrite();
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('./application/controllers')
           ->setRouter($router)
           ->setBaseUrl('/projects/myapp'); // set the base url!
$response   = $controller->dispatch();
[Note] No se admite una URL totalmente cualificada

No se admite pasar una URL totalmente cualificada (por ejemplo: http://example.com/) al método setBaseUrl, y causará problemas tanto para el uso descrito anteriormente como al usar el helper de vista URL. Consulte el ticket ZF-10923 para más detalles.

24.4.2.3. Determinación del método de la petición

getMethod() le permite determinar el método de petición HTTP usado para solicitar el recurso actual. Adicionalmente, existen varios métodos que le permiten obtener respuestas booleanas al preguntar si se ha realizado un tipo específico de petición:

  • isGet()

  • isPost()

  • isPut()

  • isDelete()

  • isHead()

  • isOptions()

El principal caso de uso para estos es la creación de arquitecturas MVC RESTful.

24.4.2.4. Detección de peticiones AJAX

Zend_Controller_Request_Http tiene un método rudimentario para detectar peticiones AJAX: isXmlHttpRequest(). Este método busca una cabecera de petición HTTP X-Requested-With con el valor 'XMLHttpRequest'; si la encuentra, devuelve TRUE.

Actualmente, se sabe que esta cabecera se envía por defecto con las siguientes bibliotecas JS:

  • Prototype y Scriptaculous (y bibliotecas derivadas de Prototype)

  • Yahoo! UI Library

  • jQuery

  • MochiKit

La mayoría de las bibliotecas AJAX le permiten enviar cabeceras de petición HTTP personalizadas; si su biblioteca no envía esta cabecera, simplemente añádala como cabecera de petición para asegurarse de que el método isXmlHttpRequest() funcione para usted.

24.4.3. Creación de subclases del objeto Request

La clase request base usada para todos los objetos request es la clase abstracta Zend_Controller_Request_Abstract. En su forma más básica, define los siguientes métodos:

abstract class Zend_Controller_Request_Abstract
{
    /**
     * @return string
     */
    public function getControllerName();

    /**
     * @param string $value
     * @return self
     */
    public function setControllerName($value);

    /**
     * @return string
     */
    public function getActionName();

    /**
     * @param string $value
     * @return self
     */
    public function setActionName($value);

    /**
     * @return string
     */
    public function getControllerKey();

    /**
     * @param string $key
     * @return self
     */
    public function setControllerKey($key);

    /**
     * @return string
     */
    public function getActionKey();

    /**
     * @param string $key
     * @return self
     */
    public function setActionKey($key);

    /**
     * @param string $key
     * @return mixed
     */
    public function getParam($key);

    /**
     * @param string $key
     * @param mixed $value
     * @return self
     */
    public function setParam($key, $value);

    /**
     * @return array
     */
     public function getParams();

    /**
     * @param array $array
     * @return self
     */
    public function setParams(array $array);

    /**
     * @param boolean $flag
     * @return self
     */
    public function setDispatched($flag = true);

    /**
     * @return boolean
     */
    public function isDispatched();
}

El objeto request es un contenedor para el entorno de la petición. La cadena del controlador solo necesita saber cómo establecer y obtener el controlador, la acción, los parámetros opcionales y el estado de despacho. Por defecto, el request buscará en sus propios parámetros usando las claves de controlador o acción para determinar el controlador y la acción.

Extienda esta clase, o una de sus derivadas, cuando necesite que la clase request interactúe con un entorno específico para obtener datos para usar en las tareas anteriores. Ejemplos incluyen el entorno HTTP, un entorno CLI, o un entorno PHP-GTK.