Depurar nuestro código de PHP es uno de los pasos más importantes de la programación. Una gran ayuda que tenemos a nuestra disposición son los logs o archivos de log.
Hoy veremos cómo escribir mensajes de error y depuración (o debug) en archivos de texto usando PHP sin usar librerías externas, únicamente funciones nativas y un poco de código al inicio de nuestro script.
Gracias a esto podremos escribir mensajes de información y también llevar un registro de errores sin mostrarlos al usuario, con fecha y hora de llamada así como el script de llamada.
Un ejemplo del log que vamos a crear (esto dependerá de tu app pero para que te des una idea) es este:
[07-Feb-2019 09:37:29 America/Mexico_City] Soy un mensaje
[07-Feb-2019 09:37:29 America/Mexico_City] PHP Warning: Division by zero in D:\desarrollo_php\htdocs\loguear\index.php on line 9
[07-Feb-2019 09:37:29 America/Mexico_City] Mensaje desde la línea 12 del archivo D:\desarrollo_php\htdocs\loguear\index.php
[07-Feb-2019 09:37:29 America/Mexico_City] Hola, yo soy parzibyte y mi sitio es parzibyte.me
[07-Feb-2019 09:37:29 America/Mexico_City] Los personajes son: a:4:{i:0;s:5:"Crash";i:1;s:10:"Fake Crash";i:2;s:4:"Pura";i:3;s:5:"Polar";}
[07-Feb-2019 09:37:29 America/Mexico_City] La mascota: array (
'nombre' => 'Maggie',
'edad' => 3,
'amigos' =>
array (
0 =>
array (
'nombre' => 'Guayaba',
'edad' => 2,
),
1 =>
array (
'nombre' => 'Meca',
'edad' => 5,
),
2 =>
array (
'nombre' => 'Snowball',
'edad' => 2,
),
),
)
[07-Feb-2019 09:37:29 America/Mexico_City] PHP Fatal error: Uncaught Exception: Yo soy una excepción muy malvada in D:\desarrollo_php\htdocs\loguear\index.php:48
Stack trace:
#0 {main}
thrown in D:\desarrollo_php\htdocs\loguear\index.php on line 48
Veamos entonces cómo loguear con PHP, además de evitar mostrar los errores al usuario, asegurando nuestras aplicaciones web.
El propósito de un error log es:
Entonces nuestro archivo en donde configuramos todo eso debe quedar así:
<?php
/**
* Un simple archivo que configura el log, oculta
* los errores y crea un nuevo archivo cada día
*
* @author parzibyte
*/# El directorio o carpeta en donde se van a crear los logs
# da algo como C:\xampp\esta_carpeta\logs
define("RUTA_LOGS", __DIR__ . "/logs");
# Crear carpeta si no existe
if (!file_exists(RUTA_LOGS)) {
mkdir(RUTA_LOGS);
}
# Poner fecha y hora de México, esto es por si el servidor tiene
# otra zona horaria
date_default_timezone_set("America/Mexico_City");
# Configuramos el ini para que...
# No muestre errores
ini_set('display_errors', 0);
# Los ponga en un archivo
ini_set("log_errors", 1);
# Y le indicamos en dónde los va a poner, sería en algo como:
# RUTA_LOGS/2019-02-07.log
# Así cada día tenemos un archivo de log distinto
ini_set("error_log", RUTA_LOGS . "/" . date("Y-m-d") . ".log");
# Listo, ahora asegúrate de incluir lo de arriba en el encabezado o un archivo
# común que se ejecute siempre al inicio
Para usarlo simplemente hay que incluirlo en la parte superior de nuestros archivos en donde lo vamos a ocupar y, a partir de ello, cualquier error se va a ocultar al usuario y en su lugar se va a imprimir en el archivo.
Como vemos, cada día se creará un nuevo archivo y tendrá como nombre la fecha que indicará el año, mes y día. De esta manera, podemos ver los errores que han ocurrido con el paso del tiempo.
Recuerda que todos los archivos de log serán creados en la carpeta definida por RUTA_LOGS
, puedes cambiarla según tus necesidades.
Los ajustes en donde llamamos a ini_set son para modificar el archivo ini de PHP y, en el orden en el que aparecen hacen lo siguiente:
display_errors
en 0log_errors
en 1error_log
y pasándole la ruta del fichero.Más abajo veremos un ejemplo. Te recomiendo ver cómo trabajar con archivos en PHP.
Podemos depurar llamando a error_log
y pasándole un mensaje. En caso de que se genere un error, será impreso en el archivo.
Finalmente, si se produce una excepción no controlada, también se pondrá en el log y se le mostrará al usuario el mensaje de “Esta página no funciona”.
Para usar el logger simplemente inclúyelo en donde lo vas a usar, recomiendo incluirlo antes que todo. En mi caso queda así y hago algunas pruebas:
<?php
/**
* Probar logger que acabamos de crear, imprimiendo algunos
* mensajes de depuración, produciendo errores o lanzando
* excepciones
*
* @author parzibyte
*/# Incluir "logger"
include_once "logger.php";
# Probemos enviando un simple error...
error_log("Soy un mensaje");
# División entre 0
$resultado = 1 / 0;
# Loguear cualquier cosa, incluso con la línea
error_log("Mensaje desde la línea " . __LINE__ . " del archivo " . __FILE__);
# ¿Variables? claro, al final simplemente debes pasar un string
$usuario = "parzibyte";
$sitio_web = "parzibyte.me";
error_log("Hola, yo soy $usuario y mi sitio es $sitio_web");
# También se pueden serializar algunas cosas, pero no serán legibles
# Recomiendo: https://parzibyte.me/blog/2018/10/11/sintaxis-corta-array-php/
$personajes = ["Crash", "Fake Crash", "Pura", "Polar"];
error_log("Los personajes son: " . serialize($personajes));
# Y si quieres un var_dump para detalles de cualquier variable,
# usa var_export como lo menciono en mi post:
# https://parzibyte.me/blog/2018/05/18/alternativa-var_dump-php-detalles-variable/
$mascota = [
"nombre" => "Maggie",
"edad" => 3,
"amigos" => [
[
"nombre" => "Guayaba",
"edad" => 2,
],
[
"nombre" => "Meca",
"edad" => 5,
],
[
"nombre" => "Snowball",
"edad" => 2,
],
],
];
error_log("La mascota: " . var_export($mascota, true));
# Lanzar excepción, lo ponemos al final porque detiene el script
throw new Exception("Yo soy una excepción muy malvada");
error_log("Esto no se escribe porque la excepción de arriba detiene el script");
El script fue para probar, pero si alguna función o clase produce un error, será logueado en el archivo. De esta manera tendrás un registro de todos los movimientos que se hacen.
Te invito a ver más sobre var_export y la notación corta de los arreglos.
Por cierto, cabe mencionar que nunca en tu vida debes loguear contraseñas o claves de acceso en un log, es una mala práctica y una posible vulnerabilidad.
Ya lo dije hace un momento, puedes mover la carpeta de logs a un directorio no público, pero en caso de que lo dejes en el mismo, debes protegerlo y restringirlo, porque cualquier usuario podría ver la carpeta (y su contenido) desde el navegador:
Dependiendo de tu servidor puedes aplicar distintas configuraciones, en este caso lo haré con Apache. Creamos un archivo llamado .htaccess
(mira cómo habilitarlo si no lo está) y su contenido es el siguiente:
Allow from None
Order allow,deny
Ahora cuando alguien quiere entrar a la carpeta, se muestra esto:
Mira más sobre denegar o proteger acceso a carpetas y archivos con Apache.
Y no te preocupes, tampoco se puede acceder a los archivos individuales; pero tú sí podrás verlos desde FTP o el sistema de archivos, además de que PHP podrá seguir escribiendo. En resumen, los archivos de log se restringen al público.
¿Quieres leer más sobre PHP? haz click aquí.
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…
Esta web usa cookies.
Ver comentarios