Hace una semana vi que añadieron al trunk de PHP una nueva función llamada header_register_callback.

La función permite procesar, mediante un callback, todos los headers (los generados por el usuario explícitamente, más los que genera PHP internamente) inmediatamente antes de que se manden. Permitiendo utilizar las funciones relacionadas con los headers: headers_list, header_remove, header.

Ejemplo incluído:

header('Content-Type: text/plain');  
header('X-Test: foo');  

function foo() {  
    foreach (headers_list() as $header) {  
        if (strpos($header, 'X-Powered') !== false) {  
            header_remove('X-Powered-By');  
        }  
    }  
    header_remove('X-Test');  
}  

$result = header_register_callback('foo');  
echo "a";

En el ejemplo que incluyen borran un header personalizado y el header añadido por PHP X-Powered-By. Evitando que un usuario malintencionado disponga de la versión de PHP que estamos usando e incluso reduciendo unos bytes las cabeceras que se están mandando en cada petición. (El X-Powered-By se puede deshabilitar mediante la configuración “expose_php = Off” en el php.ini).

Cabe destacar que los headers a los que tienes acceso son a los generados por PHP, todo lo que ocurra después no lo vas a poder manipular directamente. Los headers que genera PHP se pasan al servidor HTTP: apache, lighthttpd, cherokee

Además de para borrar headers puede servir para verificar que los headers sean correctos. Supongamos que tenemos un framework que permite hacer redirecciones indirectamente. Podemos verificar que no se ha llamado a header(‘Location: …’); a pelo, sino mediante nuestro framework, guardándonos por ejemplo si se llamó al código de nuestro framework.

Si usamos alguna extensión de nuestro servidor HTTP como la gestión de la cabecera X-SendFile, podemos verificar que el archivo que se pretende servir esté en los valores esperados.

Conclusión: La posibilidad de disponer de nuevos hooks siempre es bienvenida.

Otros hooks interesantes:

  • **register_shutdown_function **- Registrar un callback antes de finalizar la ejecución. (Útil para despliegue de información de debug y para medir tiempos)
  • register_tick_function - Registrar un callback que se ejecuta cada X opcodes del intérprete. Útil para medir eficiencia a nivel de opcodes sin usar extensiones y para otros casos más bizarros que ya comentaré en otra ocasión.
  • spl_autoload_register - Registrar un hook que se ejecuta cuando una clase no existe, para dar la opción a declararla. (Extremadamente útil para lazy loading de clases.)
  • set_exception_handler - Registra un manejador de excepciones para cuando no se ha podido manejar. Viene bien para detectar errores inesperados, logear dichos errores, mandar emails…
  • set_error_handler - Similar al gestor de excepciones pero con errores.
  • session_set_save_handler - Permite definir las funciones que gestionarán todo lo relacionado con el sistema de sesiones de PHP. Viene bien para utilizar otros sistemas para el guardado de sesiones, como base de datos, memcached, sharedance, shm…
  • stream_wrapper_register - Permite registrar manejadores de protocolo como clases de PHP.