TigerZF
🌐Español

38.4. Zend_Http_Cookie y Zend_Http_CookieJar

38.4.1. Introducción

Zend_Http_Cookie, como cabría esperar, es una clase que representa una cookie HTTP. Proporciona métodos para analizar cadenas de respuesta HTTP, recopilar cookies, y acceder fácilmente a sus propiedades. También permite comprobar si una cookie coincide con un escenario específico, es decir, una URL de petición, tiempo de expiración, conexión segura, etc.

Zend_Http_CookieJar es un objeto normalmente usado por Zend_Http_Client para mantener un conjunto de objetos Zend_Http_Cookie. La idea es que si un objeto Zend_Http_CookieJar se adjunta a un objeto Zend_Http_Client, todas las cookies que entren y salgan del cliente a través de peticiones y respuestas HTTP serán almacenadas por el objeto CookieJar. Después, cuando el cliente envíe otra petición, primero preguntará al objeto CookieJar por todas las cookies que coincidan con la petición. Estas se añadirán a las cabeceras de la petición automáticamente. Esto es muy útil en casos donde se necesita mantener una sesión de usuario a lo largo de peticiones HTTP consecutivas, enviando automáticamente las cookies del ID de sesión cuando sea necesario. Además, el objeto Zend_Http_CookieJar puede serializarse y almacenarse en $_SESSION cuando sea necesario.

38.4.2. Instanciando objetos Zend_Http_Cookie

Instanciar un objeto Cookie puede hacerse de dos formas:

  • A través del constructor, usando la siguiente sintaxis: new Zend_Http_Cookie(string $name, string $value, string $domain, [int $expires, [string $path, [boolean $secure]]]);

    • $name: El nombre de la cookie (ej. 'PHPSESSID') (obligatorio)

    • $value: El valor de la cookie (obligatorio)

    • $domain: El dominio de la cookie (ej. '.example.com') (obligatorio)

    • $expires: Tiempo de expiración de la cookie, como marca de tiempo UNIX (opcional, por defecto NULL). Si no se establece, la cookie se tratará como una 'cookie de sesión' sin tiempo de expiración.

    • $path: Ruta de la cookie, ej. '/foo/bar/' (opcional, por defecto '/')

    • $secure: Booleano, indica si la cookie debe enviarse solo a través de conexiones seguras (HTTPS) (opcional, por defecto FALSE)

  • Llamando al método estático fromString($cookieStr, [$refUri, [$encodeValue]]), con una cadena de cookie tal como se representa en la cabecera de respuesta HTTP 'Set-Cookie' o en la cabecera de petición 'Cookie' HTTP. En este caso, el valor de la cookie ya debe estar codificado. Cuando la cadena de la cookie no contiene una parte 'domain', debe proporcionar una URI de referencia según la cual se establecerán el dominio y la ruta de la cookie.

    El método fromString() acepta los siguientes parámetros:

    • $cookieStr: una cadena de cookie tal como se representa en la cabecera de respuesta HTTP 'Set-Cookie' o en la cabecera de petición HTTP 'Cookie' (obligatorio)

    • $refUri: una URI de referencia según la cual se establecerán el dominio y la ruta de la cookie. (opcional, por defecto analiza el valor desde $cookieStr)

    • $encodeValue: Si el valor debe pasarse por urldecode. También afecta al comportamiento de la cookie al convertirse de nuevo en una cadena de cookie. (opcional, por defecto true)

Ejemplo 38.26. Instanciar un objeto Zend_Http_Cookie

// First, using the constructor. This cookie will expire in 2 hours
$cookie = new Zend_Http_Cookie('foo',
                               'bar',
                               '.example.com',
                               time() + 7200,
                               '/path');

// You can also take the HTTP response Set-Cookie header and use it.
// This cookie is similar to the previous one, only it will not expire, and
// will only be sent over secure connections
$cookie = Zend_Http_Cookie::fromString('foo=bar; domain=.example.com; ' .
                                       'path=/path; secure');

// If the cookie's domain is not set, you have to manually specify it
$cookie = Zend_Http_Cookie::fromString('foo=bar; secure;',
                                       'http://www.example.com/path');


[Note] Nota

Cuando se instancia un objeto cookie usando el método Zend_Http_Cookie::fromString(), se espera que el valor de la cookie esté codificado en URL, tal como deben estarlo las cadenas de cookie. Sin embargo, al usar el constructor, se espera que la cadena de valor de la cookie sea el valor real, decodificado.

Un objeto cookie puede convertirse de nuevo en una cadena, usando el método mágico __toString(). Este método producirá una cadena de cabecera "Cookie" de petición HTTP, mostrando el nombre y valor de la cookie, y terminada por un punto y coma (';'). El valor estará codificado en URL, como se espera en una cabecera Cookie:

Ejemplo 38.27. Convertir un objeto Zend_Http_Cookie a cadena

// Create a new cookie
$cookie = new Zend_Http_Cookie('foo',
                               'two words',
                               '.example.com',
                               time() + 7200,
                               '/path');

// Will print out 'foo=two+words;' :
echo $cookie->__toString();

// This is actually the same:
echo (string) $cookie;

// In PHP 5.2 and higher, this also works:
echo $cookie;


38.4.3. Métodos getter de Zend_Http_Cookie

Una vez que se ha instanciado un objeto Zend_Http_Cookie, este proporciona varios métodos getter para obtener las diferentes propiedades de la cookie HTTP:

  • getName(): Obtiene el nombre de la cookie

  • getValue(): Obtiene el valor real, decodificado, de la cookie

  • getDomain(): Obtiene el dominio de la cookie

  • getPath(): Obtiene la ruta de la cookie, que por defecto es '/'

  • getExpiryTime(): Obtiene el tiempo de expiración de la cookie, como marca de tiempo UNIX. Si la cookie no tiene tiempo de expiración establecido, devolverá NULL.

Además, se proporcionan varios métodos comprobadores booleanos:

  • isSecure(): Comprueba si la cookie está configurada para enviarse solo a través de conexiones seguras. En términos generales, si es TRUE la cookie solo debería enviarse a través de HTTPS.

  • isExpired(int $time = null): Comprueba si la cookie ha expirado o no. Si la cookie no tiene tiempo de expiración, siempre devolverá TRUE. Si se proporciona $time, sobrescribirá la marca de tiempo actual como el momento contra el que comprobar la cookie.

  • isSessionCookie(): Comprueba si la cookie es una "cookie de sesión" - es decir, una cookie sin tiempo de expiración, destinada a expirar cuando finalice la sesión.

Ejemplo 38.28. Uso de métodos getter con Zend_Http_Cookie

// First, create the cookie
$cookie =
    Zend_Http_Cookie::fromString('foo=two+words; ' +
                                 'domain=.example.com; ' +
                                 'path=/somedir; ' +
                                 'secure; ' +
                                 'expires=Wednesday, 28-Feb-05 20:41:22 UTC');

echo $cookie->getName();   // Will echo 'foo'
echo $cookie->getValue();  // will echo 'two words'
echo $cookie->getDomain(); // Will echo '.example.com'
echo $cookie->getPath();   // Will echo '/'

echo date('Y-m-d', $cookie->getExpiryTime());
// Will echo '2005-02-28'

echo ($cookie->isExpired() ? 'Yes' : 'No');
// Will echo 'Yes'

echo ($cookie->isExpired(strtotime('2005-01-01') ? 'Yes' : 'No');
// Will echo 'No'

echo ($cookie->isSessionCookie() ? 'Yes' : 'No');
// Will echo 'No'


38.4.4. Zend_Http_Cookie: Comparación contra un escenario

La única lógica real contenida en un objeto Zend_Http_Cookie, está en el método match(). Este método se usa para comprobar una cookie contra un escenario de petición HTTP dado, para determinar si la cookie debe enviarse en esta petición o no. El método tiene la siguiente sintaxis y parámetros: Zend_Http_Cookie->match(mixed $uri, [boolean $matchSessionCookies, [int $now]]);

  • $uri: Un objeto Zend_Uri_Http con un nombre de dominio y una ruta a comprobar. Opcionalmente, se puede pasar en su lugar una cadena que represente una URL HTTP válida. La cookie coincidirá si el esquema de la URL (HTTP o HTTPS), el dominio y la ruta coinciden todos.

  • $matchSessionCookies: Si deben coincidir las cookies de sesión o no. Por defecto TRUE. Si se establece en FALSE, las cookies sin tiempo de expiración nunca coincidirán.

  • $now: Momento (representado como marca de tiempo UNIX) contra el que comprobar la expiración de una cookie. Si no se especifica, por defecto será el momento actual.

Ejemplo 38.29. Comparación de cookies

// Create the cookie object - first, a secure session cookie
$cookie = Zend_Http_Cookie::fromString('foo=two+words; ' +
                                       'domain=.example.com; ' +
                                       'path=/somedir; ' +
                                       'secure;');

$cookie->match('https://www.example.com/somedir/foo.php');
// Will return true

$cookie->match('http://www.example.com/somedir/foo.php');
// Will return false, because the connection is not secure

$cookie->match('https://otherexample.com/somedir/foo.php');
// Will return false, because the domain is wrong

$cookie->match('https://example.com/foo.php');
// Will return false, because the path is wrong

$cookie->match('https://www.example.com/somedir/foo.php', false);
// Will return false, because session cookies are not matched

$cookie->match('https://sub.domain.example.com/somedir/otherdir/foo.php');
// Will return true

// Create another cookie object - now, not secure, with expiration time
// in two hours
$cookie = Zend_Http_Cookie::fromString('foo=two+words; ' +
                                       'domain=www.example.com; ' +
                                       'expires='
                                       . date(DATE_COOKIE, time() + 7200));

$cookie->match('http://www.example.com/');
// Will return true

$cookie->match('https://www.example.com/');
// Will return true - non secure cookies can go over secure connections
// as well!

$cookie->match('http://subdomain.example.com/');
// Will return false, because the domain is wrong

$cookie->match('http://www.example.com/', true, time() + (3 * 3600));
// Will return false, because we added a time offset of +3 hours to
// current time


38.4.5. La clase Zend_Http_CookieJar: Instanciación

En la mayoría de los casos, no es necesario instanciar directamente un objeto Zend_Http_CookieJar. Si desea adjuntar un nuevo cookie jar a su objeto Zend_Http_Client, simplemente llame al método Zend_Http_Client->setCookieJar(), y se adjuntará a su cliente un nuevo cookie jar vacío. Más adelante podrá obtener este cookie jar usando Zend_Http_Client->getCookieJar().

Si aun así desea instanciar manualmente un objeto CookieJar, puede hacerlo llamando directamente a "new Zend_Http_CookieJar()" - el método constructor no toma ningún parámetro. Otra forma de instanciar un objeto CookieJar es usar el método estático Zend_Http_CookieJar::fromResponse(). Este método toma dos parámetros: un objeto Zend_Http_Response, y una URI de referencia, ya sea como cadena o como objeto Zend_Uri_Http. Este método devolverá un nuevo objeto Zend_Http_CookieJar, que ya contiene las cookies establecidas por la respuesta HTTP pasada. La URI de referencia se usará para establecer el dominio y la ruta de la cookie, si no están definidos en las cabeceras Set-Cookie.

38.4.6. Añadir cookies a un objeto Zend_Http_CookieJar

Normalmente, el objeto Zend_Http_Client al que adjuntó su objeto CookieJar añadirá automáticamente las cookies establecidas por las respuestas HTTP a su jar. Si desea añadir cookies manualmente a su jar, esto puede hacerse usando dos métodos:

  • Zend_Http_CookieJar->addCookie($cookie[, $ref_uri]): Añade una única cookie al jar. $cookie puede ser un objeto Zend_Http_Cookie o una cadena, que se convertirá automáticamente en un objeto Cookie. Si se proporciona una cadena, también debería proporcionar $ref_uri - que es una URI de referencia, ya sea como cadena u objeto Zend_Uri_Http, para usar como dominio y ruta por defecto de la cookie.

  • Zend_Http_CookieJar->addCookiesFromResponse($response, $ref_uri): Añade todas las cookies establecidas en una única respuesta HTTP al jar. Se espera que $response sea un objeto Zend_Http_Response con cabeceras Set-Cookie. $ref_uri es la URI de la petición, ya sea como cadena o como objeto Zend_Uri_Http, según la cual se establecerán el dominio y la ruta por defecto de las cookies.

38.4.7. Recuperar cookies de un objeto Zend_Http_CookieJar

Al igual que al añadir cookies, normalmente no es necesario obtener manualmente las cookies de un objeto CookieJar. Su objeto Zend_Http_Client obtendrá automáticamente las cookies necesarias para una petición HTTP por usted. Sin embargo, aún puede usar 3 métodos proporcionados para obtener cookies del objeto jar: getCookie(), getAllCookies(), y getMatchingCookies(). Además, iterar sobre el CookieJar le permitirá recuperar todos los objetos Zend_Http_Cookie que contiene.

Es importante notar que cada uno de estos métodos toma un parámetro especial, que establece el tipo de retorno del método. Este parámetro puede tener 3 valores:

  • Zend_Http_CookieJar::COOKIE_OBJECT: Devuelve un objeto Zend_Http_Cookie. Si el método devuelve más de una cookie, se devolverá un array de objetos.

  • Zend_Http_CookieJar::COOKIE_STRING_ARRAY: Devuelve las cookies como cadenas, en formato "foo=bar", adecuado para enviarse en una cabecera "Cookie" de petición HTTP. Si se devuelve más de una cookie, se devuelve un array de cadenas.

  • Zend_Http_CookieJar::COOKIE_STRING_CONCAT: Similar a COOKIE_STRING_ARRAY, pero si se devuelve más de una cookie, este método concatenará todas las cookies en una única cadena larga separada por puntos y comas (;), y la devolverá. Esto es especialmente útil si desea enviar directamente todas las cookies coincidentes en una única cabecera "Cookie" de petición HTTP.

  • Zend_Http_CookieJar::COOKIE_STRING_CONCAT_STRICT: Similar a COOKIE_STRING_CONCAT, pero sigue una implementación estricta de RFC6265. En este modo, siempre sigue un único carácter de espacio al separador de punto y coma entre cookies, y el separador de punto y coma se elimina del final de la cadena de cookie.

La estructura de los diferentes métodos de obtención de cookies se describe a continuación:

  • Zend_Http_CookieJar->getCookie($uri, $cookie_name[, $ret_as]): Obtiene una única cookie del jar, según su URI (dominio y ruta) y nombre. $uri es una cadena o un objeto Zend_Uri_Http que representa la URI. $cookie_name es una cadena que identifica el nombre de la cookie. $ret_as especifica el tipo de retorno como se describe arriba. $ret_type es opcional, y por defecto es COOKIE_OBJECT.

  • Zend_Http_CookieJar->getAllCookies($ret_as): Obtiene todas las cookies del jar. $ret_as especifica el tipo de retorno como se describe arriba. Si no se especifica, $ret_type por defecto es COOKIE_OBJECT.

  • Zend_Http_CookieJar->getMatchingCookies($uri[, $matchSessionCookies[, $ret_as[, $now]]]): Obtiene todas las cookies del jar que coinciden con un escenario especificado, es decir, una URI y un tiempo de expiración.

    • $uri es un objeto Zend_Uri_Http o una cadena que especifica el tipo de conexión (segura o no segura), dominio y ruta contra los que comparar.

    • $matchSessionCookies es un booleano que indica si se deben comparar las cookies de sesión o no. Las cookies de sesión son cookies que no tienen tiempo de expiración especificado. Por defecto TRUE.

    • $ret_as especifica el tipo de retorno como se describe arriba. Si no se especifica, por defecto es COOKIE_OBJECT.

    • $now es un entero que representa la marca de tiempo UNIX a considerar como "ahora" - es decir, cualquier cookie configurada para expirar antes de este momento no coincidirá. Si no se especifica, por defecto es el momento actual.

    Puede leer más sobre la comparación de cookies en esta sección.