Cuando hacemos una página en php, normalmente la solemos hacer para que muestre contenido de texto ya formateado (en html si es para un navegador, en xml si es para un servicio web, etc). Cuando digo formateado me refiero a que no solo contiene contenido textual, sino que también contiene etiquetas de formato, etiquetas pertenecientes al tipo de documento, comentarios, códigos, etc. Esto al final provoca que haya mucha saturación en cuanto a contenido, o dicho de otra forma, se envían muchos bytes.
El problema radica en que por un lado se esta gastando un ancho de banda que pudiera servir para otras cosas (como es el caso de los hosting, donde tiene un limite de transferencia mensual) y al mismo tiempo provoca que se tarde más tiempo en descargar esa información (especialmente si estamos hablando de modems).
La solución pasa por comprimir la salida del php y que el navegador del cliente se encargue de descomprimirla. Para ello hace ya tiempo que se añadió al estardar HTTP 1.1 la cabecera Accept-Enconding. Esta cabecera es enviada por el navegador al servidor web y contiene una lista de métodos de codificación de contenido que el navegador puede tratar. En el caso del Firefox o del Internet Explorer esta lista es gzip y deflate. El gzip es el método que nos interesa, ya que con el, se comprime la salida. Así que si el navegador pide al servidor un página php (y esta permite comprimirla como veremos a continuación), el documento que el servidor entrega al navegador estará comprimido (con una cabecera a su vez denominada Content-Encoding), con el consecuente ahorro de tiempo de transferencia y cantidad de datos a transmitir. Teniendo en cuenta que casi siempre suele ser texto lo que se envía, la compresión se hace mucho mejor, ya que se repite mayor cantidad de carácteres.
Ejemplo de petición del navegador Firefox:
GET /divisas/divisas.php HTTP/1.1
Host: www.quejateportodo.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.7.5) Gecko/20041108 Firefox/1.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Ejemplo de petición del navegador Internet Explorer:
GET /divisas/divisas.php?idioma=es&fecha=09/04/2005&version=201&codigo=21988 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host: www.quejateportodo.com
Connection: Keep-Alive
Cookie: PHPSESSID=09b4f65e7adf47e857a309d5a9ef83e3
A lo que en mi caso el servidor devuelve esta respuesta similar en ambos casos:
HTTP/1.1 200 OK
Date: Sat, 09 Apr 2005 16:49:14 GMT
Server: Apache/1.3.33 (Unix) mod_gzip/1.3.26.1a mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.3.10 FrontPage/5.0.2.2635 mod_ssl/2.8.22 OpenSSL/0.9.7a
X-Powered-By: PHP/4.3.10
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Last-Modified: Sat, 09 Apr 2005 16:49:14 GMT
Cache-Control: post-check=0, pre-check=0
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: text/xml
Age: 496
Connection: close
Y después de tanta teoría, la práctica:
<?
ob_start(«ob_gzhandler»);
… Aquí se mete toda la lógica del php …
ob_end_flush();
?>
¿A que resulta muy curioso que sea tán extremadamente sencillo el hacerlo?. Primero ponemos al principio del todo de la página php la instrucción ob_start del php, que sirve para activar el modo «buffering», que no es otra cosa que primero genera la página y luego la envia en vez de irla enviando a medida que se va generando. Hay que pasarle el parámetro de texto ob_gzhandler para que al final comprima todo lo que tiene en el buffer antes de enviarlo. Finalmente ponemos ob_end_flush al final del todo de la página php, que sirve para cerrar el buffer y enviarlo todo.
Y para terminar, solo deciros que lo useis, ya que os supondrá un ahorro bastante efectivo. Si quereis comprobar si lo teneis instalado en vuestro servidor, buscad las librerias zlib, zend y la variable output_buffering a 1 en un phpinfo.