Cookies

En esta lección se trata el manejo de las cookies. Las cookies (“galletas”, en inglés) son un mecanismo que utilizan los servidores web para guardar información en el ordenador del usuario y recuperarla cada vez que el navegador les pide una página. La información se guarda en el ordenador del usuario en forma de texto y está formada por parejas (nombre de la cookie y valor de la cookie). Esta información se utiliza para numerosos fines (autentificación, selección de preferencias, items seleccionados en un carrito de la compra, etc.), siempre con la intención de identificar al usuario y personalizar las páginas. En el manual de PHP se ofrece un capítulo dedicado a las cookies.

Crear cookies

Las cookies se crean cuando el servidor se lo pide al navegador. Cuando el servidor envía una página al navegador, puede incluir en las cabeceras de la respuesta HTTP la petición de creación de una o varias cookies. El navegador crea la cookie, guardando no sólo el nombre y el valor de la cookie, sino el nombre del servidor (del dominio) que ha creado la cookie.

En PHP, las cookies se crean mediante la función setcookie(). Por ejemplo:

<?php
setcookie("nombre", "Pepito Conejo");
?>

Si se quiere guardar en una cookie una matriz de datos, es necesario crear cada elemento de la matriz en una cookie distinta. Por ejemplo:

<?php
setcookie("datos[nombre]", "Pepito");
setcookie("datos[apellidos]", "Conejo");
?>

Es muy importante que los nombres de las cookies no coincidan con los nombres de controles de los formularios, porque PHP incluye los valores de las cookies en la matriz $_REQUEST. Es decir, que si el nombre de una cookie coincide con el nombre de un control, en $_REQUEST sólo se guardará el valor de la cookie, no el del control.


Hay que tener la precaución de utilizar la función setcookie() antes de empezar a escribir el contenido de la página, porque si no PHP producirá un aviso y no se creará la cookie. El motivo es que las cookies se crean mediante cabeceras de respuesta HTTP y las cabeceras se envían antes del texto de la página. Es decir, cuando PHP encuentra una instrucción que escribe texto, cierra automáticamente la cabecera; si a continuación PHP encuentra en el programa la función setcookie(), da un aviso porque ya se han enviado las cabeceras y no se crea la cookie. El ejemplo siguiente muestra código incorrecto, ya que utiliza la función setcookie() después de haber escrito texto, y el mensaje de aviso generado por PHP.

<?php
// Este código es incorrecto, la cabecera se crea después de crear texto
print "<p>Hola</p>\n";
setcookie("nombre", "Pepito Conejo");
?>
<p>Hola</p>
Warning: Cannot modify header information - headers
already sent by (output started at prueba.php on
line 3) in prueba.php on line 4

Nota: En algunos casos este código incorrecto puede no generar un aviso y la cookie puede crearse, dependiendo de la configuración de la directiva output_buffering.


La creación de cookies tiene límites, pero cada navegador tiene un límite distinto. En muchas páginas web se puede leer que el límite por dominio suele ser de 20 cookies (si se hacen más, se borran las más antiguas), que el límite de tamaño del valor almacenado suele ser de 4096 bytes y que el límite del número total de cookies suele ser de 300 cookies, pero estos valores pueden ser distintos en versiones más recientes.


La función setcookie() puede tener hasta siete argumentos: setcookie($nombre, $valor, $expiracion, $ruta, $dominio, $seguridad, $solohttp)

$nombre
Establece el nombre de la cookie.
$valor
Establece el valor que guarda la cookie
$expiracion
Establece el momento en que se borrará la cookie, expresado como tiempo Unix. Por ello, normalmente se utiliza la función time() (que indica el momento actual como tiempo Unix) más la duración en segundos que queremos que tenga la cookie
<?php
setcookie("nombre", "Pepito Conejo", time() + 60);  // Esta cookie se borrará un minuto después de crearla.
?>

Si no se establece la duración de la cookie al crearla, la cookie se borrará al cerrar el navegador.

$ruta
Establece los directorios del dominio a los que se enviará posteriormente la cookie. Es decir, si el navegador solicita una página incluida en esta ruta, el navegador enviará la cookie en la petición, si no está incluida, no enviará el valor. Si se indica "/", se enviará a cualquier página del dominio, si no se indica nada, la ruta es la de la página que crea la cookie.
$dominio
Establece los subdominios del dominio a los que se enviará posteriormente la cookie (www.example.com, subdominio.example.com, etc.
$seguridad
Establece si solamente se envía bajo conexiones seguras (https) o no, según tome el valor true o false.
$solohttp
Establece si la cookie está accesible únicamente al servidor y no al navegador (mediante Javascript u otros lenguajes), según tome el valor true o false.

Modificar cookies

Para modificar una cookie ya existente, simplemente se debe volver a crear la cookie con el nuevo valor.

Borrar cookies

Para borrar una cookie, simplemente se debe volver a crear la cookie con un tiempo de expiración anterior al presente.

<?php
setcookie("nombre", "Pepito Conejo", time() - 60);  // Esta cookie se borrará inmediatamente.
?>

Si solamente queremos borrar el valor almacenado en la cookie sin borrar la propia cookie, simplemente se debe volver a crear la cookie, sin indicarle el valor a almacenar:

<?php
setcookie("nombre");  // Esta cookie no se borra, pero no guardará ningún valor.
?>

Utilizar cookies

Cuando el navegador solicita una página PHP a un servidor (un dominio) que ha guardado previamente cookies en ese ordenador, el navegador incluye en la cabecera de la petición HTTP todas las cookies (el nombre y el valor) creadas anteriormente por ese servidor.

El programa PHP recibe los nombres y valores de las cookies y se guardan automáticamente en la matriz $_COOKIE.

El ejemplo siguiente saluda al usuario por su nombre si el nombre del usuario estaba guardado en una cookie.

<?php
if (isset($_COOKIE["nombre"])) {
    print "<p>Su nombre es $_COOKIE[nombre]</p>\n";
} else {
    print "<p>No sé su nombre.</p>\n";
}
?>

En caso de que se haya guardado una matriz en forma de cookies, el ejemplo sería el siguiente:

<?php
if (isset($_COOKIE["datos"]["nombre"]) && isset($_COOKIE["datos"]["apellidos"])) {
    print "<p>Su nombre es " . $_COOKIE["datos"]["nombre"] . " " . $_COOKIE["datos"]["apellidos"] . "</p>\n";
} else {
    print "<p>No sé su nombre.</p>\n";
}
?>

Un detalle importante a tener en cuenta al trabajar con cookies es el orden en que se realiza el envío y la creación de cookies, así como su disponibilidad en $_COOKIES:

Por ello, el siguiente programa no dará el mismo resultado cuando se ejecute por primera vez que las veces posteriores:

<?php
setcookie("nombre", "Pepito Conejo");

if (isset($_COOKIE["nombre"])) {
    print "<p>Su nombre es $_COOKIE[nombre]</p>\n";
} else {
    print "<p>No sé su nombre.</p>\n";
}
?>

La primera vez que se ejecuta este programa, ocurren las siguientes cosas en este orden:

La segunda vez (y las siguientes) que se ejecuta este programa, ocurren las siguientes cosas en este orden:

Críticas a las cookies

Aunque las cookies no son programas y por tanto no pueden contener virus ni dañar al ordenador, mucha gente desconfía de las cookies, hasta el punto que todos los navegadores incluyen opciones para impedir totalmente la creación de cookies o permitirla únicamente a sitios autorizados. Lógicamente, impedir la creación de cookies cookie puede complicar la visita de algunos sitios que basan su funcionamiento en cookies.

Algunos motivos por los que mucha gente desconfía de las cookies son los siguientes:


Como ejemplo del interés que genera el tema, se citan a continuación algunas noticias recientes (mayo de 2011) relacionadas con las cookies:

Directiva 2009/136/CE

En mayo de 2011 se ha publicado en los medios de comunicación (por ejemplo, en El País) que la Comisión Europea ha abierto procedimientos sancionadores a los países (España entre ellos) que no habían transpuesto antes del 25 de mayo de 2011 la Directiva 2009/136/CE, publicada en diciembre de 2009, que hace referencia en sus considerandos a las cookies. En el considerando número 66 se dice que:

Puede que haya terceros que deseen almacenar información sobre el equipo de un usuario o acceder a información ya almacenada, con distintos fines, que van desde los fines legítimos (como algunos tipos de cookies) hasta aquellos que suponen una intrusión injustificada en la esfera privada (como los programas espía o los virus). Resulta, por tanto, capital que los usuarios reciban una información clara y completa cuando realicen una acción que pueda dar lugar a dicho almacenamiento u obtención de acceso. El modo en que se facilite la información y se ofrezca el derecho de negativa debe ser el más sencillo posible para el usuario. Las excepciones a la obligación de facilitar información y proponer el derecho de negativa deben limitarse a aquellas situaciones en las que el almacenamiento técnico o el acceso sean estrictamente necesarios con el fin legítimo de permitir el uso de un servicio específico solicitado específicamente por el abonado o usuario. Cuando sea técnicamente posible y eficaz, de conformidad con las disposiciones pertinentes de la Directiva 95/46/CE, el consentimiento del usuario para aceptar el tratamiento de los datos puede facilitarse mediante el uso de los parámetros adecuados del navegador o de otra aplicación. La aplicación de estos requisitos debe ganar en eficacia gracias a las competencias reforzadas concedidas a las autoridades nacionales.

La referencia a las cookies ya aparecía en la Directiva 2002/58/CE, publicada en julio de 2002, que en su considerando 25 decía:

No obstante, los dispositivos de este tipo, por ejemplo los denominados «chivatos» (cookies), pueden constituir un instrumento legítimo y de gran utilidad, por ejemplo, para analizar la efectividad del diseño y de la publicidad de un sitio web y para verificar la identidad de usuarios partícipes en una transacción en línea. En los casos en que estos dispositivos, por ejemplo los denominados «chivatos» (cookies), tengan un propósito legítimo, como el de facilitar el suministro de servicios de la sociedad de la información, debe autorizarse su uso a condición de que se facilite a los usuarios información clara y precisa al respecto, de conformidad con la Directiva 95/46/CE, para garantizar que los usuarios están al corriente de la información que se introduce en el equipo terminal que están utilizando. Los usuarios deben tener la posibilidad de impedir que se almacene en su equipo terminal un «chivato» (cookie) o dispositivo semejante. Esto es particularmente importante cuando otros usuarios distintos al usuario original tienen acceso al equipo terminal y, a través de éste, a cualquier dato sensible de carácter privado almacenado en dicho equipo. La información sobre la utilización de distintos dispositivos que se vayan a instalar en el equipo terminal del usuario en la misma conexión y el derecho a impedir la instalación de tales dispositivos se pueden ofrecer en una sola vez durante una misma conexión y abarcar asimismo cualquier posible utilización futura de dichos dispositivos en conexiones posteriores. La presentación de la información y del pedido de consentimiento o posibilidad de negativa debe ser tan asequible para el usuario como sea posible. No obstante, se podrá supeditar el acceso a determinados contenidos de un sitio web a la aceptación fundada de un «chivato» (cookie) o dispositivo similar, en caso de que éste tenga un propósito legítimo.

La transposición de este punto de la directiva 2002/58/CE se encuentra en el artículo 22.2 de la Ley 34/2002 de servicios de la Sociedad de Información y comercio electrónico, que se modificó en la Ley 32/2003 General de Comunicaciones, dejándolo en los siguientes términos:

2. Cuando los prestadores de servicios empleen dispositivos de almacenamiento y recuperación de datos en equipos terminales, informarán a los destinatarios de manera clara y completa sobre su utilización y finalidad, ofreciéndoles la posibilidad de rechazar el tratamiento de los datos mediante un procedimiento sencillo y gratuito.

Lo anterior no impedirá el posible almacenamiento o acceso a datos con el fin de efectuar o facilitar técnicamente la transmisión de una comunicación por una red de comunicaciones electrónicas o, en la medida que resulte estrictamente necesario, para la prestación de un servicio de la sociedad de la información expresamente solicitado por el destinatario.

Yo no soy un abogado, pero parece ser que el problema de la legislación española es que sólo obliga a que se informe sobre las cookies de forma genérica (en una página del sitio, por ejemplo), mientras que la directiva obliga a que haya una aceptación previa de las cookies.

Catálogo de buenas prácticas en la publicidad on-line (abril 2011)

Iniciativa Do Not Track