strip_tags - La mejor manera de manejar los errores en una página php?
strip_tags wordpress (8)
Crea el controlador de errores (set_error_handler) y lanza excepciones dentro de él.
Ayudará a las funciones que no admiten excepciones.
En este momento, mis páginas se ven algo como esto:
if($_GET[''something''] == ''somevalue'')
{
$output .= ''somecode'';
// make a DB query, fetch a row
//...
$row = $stmt->Fetch(PDO::ASSOC);
if($row != null)
{
$output .= ''morecode'';
if(somethingIsOK())
{
$output .= ''yet more page output'';
}
else
{
$error = ''something is most definitely not OK.'';
}
}
else
{
$error = ''the row does not exist.'';
}
}
else
{
$error = ''something is not a valid value'';
}
if($error == '''') // no error
{
//display $output on page
}
else // an error
{
// display whatever error occurred on the page
}
La forma en que estoy haciendo las cosas funciona, pero es muy engorrosa y tediosa para lo que probablemente sea obvio: supongamos que llamo a una función en algún lugar en medio de mi código, o quiero verificar el valor de una variable, o verificar una consulta DB devolvió un resultado válido, y si falla, ¿quiero generar un error? Tendría que hacer otro bloque if / else y mover todo el código dentro del nuevo bloque if. Esto no parece una manera inteligente de hacer las cosas.
He estado leyendo sobre try / catch y he estado pensando en poner todo mi código dentro de una declaración try, luego dejo que el código se ejecute secuencialmente sin ningún bloque if / else y si algo falla, solo lanza una excepción. Por lo que he leído, eso detendría la ejecución y lo haría saltar directamente al bloque catch (del mismo modo que una instrucción if fallida irá al bloque else), donde podría dar salida al mensaje de error. ¿Pero es eso una práctica aceptable o estándar?
¿Cuál es la mejor forma de manejar errores, fatales o no, en una aplicación php que crea y genera una página HTML? No quiero simplemente morir con una pantalla en blanco, ya que sería muy poco amigable para el usuario, pero en cambio quiero mostrar un mensaje en el cuerpo de la página, permitiendo que se muestren el encabezado y el pie de página.
¡Gracias por su consejo!
El manejo de excepciones de error de PDO para consultas, y realmente todo el código debe ejecutarse a través de:
try{
}
catch{
}
finally{
}
La razón de esto es que hace que la depuración sea mucho más fácil cuando se puede identificar aproximadamente dónde en guiones largos se está produciendo un error
más información aquí: http://php.net/manual/en/language.exceptions.php
Esto es mucho más elegante y legible.
try
{
if($_GET[''something''] != ''somevalue'')
{
throw new Exception (''something is not a valid value'');
}
$output .= ''somecode'';
// make a DB query, fetch a row
//...
$row = $stmt->Fetch(PDO::ASSOC);
if($row == null)
{
throw new Exception (''the row does not exist.'');
}
$output .= ''morecode'';
if(somethingIsOK())
{
$output .= ''yet more page output'';
}
else
{
throw new Exception (''something is most definitely not OK.'');
}
echo $output;
}
catch (Exception $e)
{
echo $e->getMessage();
}
Hay muchas maneras de lidiar con esto y, francamente, ninguno de ellos es intrínsecamente "correcto".
Tendrás que decidir por ti mismo, qué método es más "cómodo" para ti, siempre es una cuestión de preferencias (aunque hay ciertas técnicas que debes evitar y por buenas razones).
Dependerá en gran medida de cómo dividir la lógica, sin embargo, tiendo a incluir todo el código que puede devolver errores no fatales dentro de una función, y utilizar un valor de retorno de dicha función para indicar que hubo un error.
Para los errores fatales , tiendo a usar excepciones (con bloques try-catch
).
Ahora solo para ser claro:
- Un error no fatal es un error del que puede recuperarse , lo que significa que, aunque algo salió mal, todavía hay algún código que puede ejecutarse y generar un resultado valioso. Por ejemplo, si desea obtener la hora actual usando el protocolo
NTP
, pero el servidor no respondió, puede decidir utilizar la función detime
local y aún mostrar algunos datos valiosos para el usuario. - Un error fatal es un error del que no podría recuperarse , lo que significa que sucedió algo realmente malo y lo único que puede hacer es decirle a su usuario que la página no puede hacer lo que se le pidió. Por ejemplo, si estaba obteniendo algunos datos de su base de datos y recibió una
SQL Exception
, no hay datos valiosos que mostrar y solo puede informar al usuario de esto.
Errores no fatales (utilizando el retorno de la función)
Un buen ejemplo del uso de los retornos de funciones como una forma de tratar problemas no fatales sería una función que intenta mostrar el contenido de algún archivo en la página cuando este no es el objetivo principal de la página (por ejemplo, usted tendría una función que muestra insignias, extraídas de un archivo de texto, en cada página; sé que esto es descabellado, pero tengan paciencia conmigo).
function getBadge($file){
$f = fopen($file,''r'');
if(!$f){
return null;
}
.. do some processing ..
return $badges;
}
$badges = getBadges(''badges.txt'');
if(!$badges){
echo "Cannot display badges.";
} else {
echo $badges;
}
.. carry on doing whatever page should be doing ..
De hecho, la función fopen
es un ejemplo de esto: volverá .
Devuelve un recurso de puntero de archivo en caso de éxito o FALSE en caso de error.
Errores fatales (usando excepciones - try-catch)
Cuando tiene que ejecutar un código porque es exactamente lo que el usuario quería (por ejemplo, leer todas las noticias de la base de datos y mostrarlas al usuario), puede usar excepciones. Tomemos un ejemplo simple: un usuario visitó su perfil y quería ver todos los mensajes que tenía (supongamos, por ahora, que están almacenados en texto sin formato). Es posible que tenga una función como:
function getMessages($user){
$messages = array();
$f = fopen("messages_$user.txt","r");
if(!$f){
throw new Exception("Could not read messages!");
}
... do some processing ...
return $messages;
}
Y úsalo así:
try{
..do some stuff..
$messages = getMessages($_SESSION[''user''])); //assuming you store username in $_SESSION
foreach($messages as $msg){
echo $msg."<br/>";
}
} catch(Exception $e){
echo "Sorry, there was an error: ".$e->getMessage();
}
Ahora esto podría ser útil, si tuviera un script de ''nivel superior'' que ejecutaría todo el otro código. Eso significa que, por ejemplo, en su index.php
solo tendría:
try{
.. execute some code, perform some functions ..
} catch(Exception $e){
echo "Sorry, there was an error: ".$e->getMessage();
}
No abusar de las excepciones!
Hagas lo que hagas, nunca uses excepciones como una forma de verificar algo de lo que puedas recuperarte. Lea otra pregunta ( Anton Gogolev tiene todos los créditos para obtener una explicación muy buena de esto, así como de otras respuestas) sobre por qué este es el caso.
Otras lecturas
Ahora no hay mejor manera de aprender a manejar los errores que intentar varias cosas y ver lo que es bueno para usted. Puede encontrar el siguiente útil:
- W3School en PHP Manejo de excepciones
- Breve tutorial sobre el manejo de errores (similar a mi método de devolución de funciones)
- Amplio tutorial sobre el manejo de errores de PHP , incluido el uso de la función
trigger_error()
, que no he mencionado porque no lo uso y no sé mucho al respecto, pero aparentemente es muy útil. Esta es una lectura particularmente buena.
Espero que esto ayude :)
Maneje el error y la advertencia de PHP correctamente utilizando las funciones de manejo de errores. (Ver ejemplo here )
La mejor manera de manejar el error en PHP es: Puede detener todos los informes de errores al agregar esta línea en la parte superior de su archivo php.
error_reporting(0);
//OR
error_reporting(''E_ALL'');
// Predefined Constant
Manejo de errores en PHP usando funciones:
- debug_backtrace - Genera una traza inversa
- debug_print_backtrace - Imprime una traza inversa
- error_clear_last - Borre el error más reciente
- error_get_last - Obtener el último error ocurrido
- error_log: envía un mensaje de error a las rutinas de manejo de errores definidas
- error_reporting: establece qué errores de PHP se informan
- restore_error_handler - Restaura la función del controlador de errores anterior
- restore_exception_handler - Restaura la función del manejador de excepciones previamente definido
- set_error_handler - Establece una función del manejador de errores definido por el usuario
- set_exception_handler - Establece una función del manejador de excepciones definido por el usuario
- trigger_error - Genera un mensaje de error / advertencia / notificación de nivel de usuario
- user_error - Alias de trigger_error
Todas las funciones que se enumeran arriba se usan para el manejo de errores en PHP.
PHP tiene una clase ErrorException , ErrorException , para traducir los errores de PHP en excepciones, que si no se manejaran, naturalmente, detendrían la ejecución.
Las excepciones han mejorado los mecanismos de manejo de errores (try catch) y una mejor información de depuración (stack traces).
Incluya esto en la parte superior de su ruta de ejecución (la configuración, o algo que se incluye primero con todo su código):
set_error_handler(function($nNumber, $strMessage, $strFilePath, $nLineNumber){
throw new /ErrorException($strMessage, 0, $nNumber, $strFilePath, $nLineNumber);
}, /*E_ALL*/ -1);
Aunque PDO admite lanzar excepciones, está desactivado por defecto, debe habilitarlo:
$pdo->setAttribute(/PDO::ATTR_ERRMODE, /PDO::ERRMODE_EXCEPTION);
Si utiliza MySQL, también desea un error para no configurar los campos obligatorios y muchos otros errores / advertencias perdonados de forma predeterminada:
$pdo->exec("SET sql_mode = ''STRICT_ALL_TABLES''");
Las excepciones se pueden manejar como en muchos otros lenguajes de programación usando try catch finally :
try
{
echo $iAmAnUndefinedVariable;
}
catch(/Throwable $exception)
{
/*[...]*/
}
Al validar cosas, simplemente genere excepciones: throw new Exception("Missing URL variable userId!");
Sería bueno si PHP hiciera una pausa limpia algún día de la función de informe de error heredado y simplemente arrojara excepciones de manera predeterminada (desaproveche error_reporting () y cambie el valor predeterminado).
Si está buscando una estructura de código que se vea bonita y funcione, podría usar el método de whitelist
que siempre uso. Por ejemplo, validar una variable $_GET
:
$error = false;
if(!isset($_GET[''var'']))
{
$error = ''Please enter var/'s value'';
}
elseif(empty($_GET[''var'']))
{
$error = ''Var shouldn/'t be empty'';
}
elseif(!ctype_alnum($_GET[''var'']))
{
$error = ''Var should be alphanumeric'';
}
//if we have no errors -> proceed to db part
if(!$error)
{
//inserting var into database table
}
Entonces, esto es todo, solo 2 bloques if/elseif
, sin anidar
Usar try-catch
es una de las soluciones más limpias que puedes usar.
He hecho un ejemplo que aún muestra el encabezado y el pie de página cuando ocurre un error, usando su código convertido al formato try-catch
:
PHP:
<?php
try {
$output = array();
if($_GET[''something''] != ''somevalue'') throw new Exception(''something does not have a valid value.'');
$output[] = ''Some Code'';
$row = mt_rand(0, 10) < 5 ? null : mt_rand(0, 100);
if($row === null) throw new Exception(''The row does not exist.'');
$output[] = $row;
if(!somethingIsOK()) throw new Exception(''Something is most definitely not OK.'');
$output[] = ''Yet more page output'';
} catch(Exception $e) {
$output[] = ''Error: '' . $e->getMessage(); // To show output and error
$output = array(''Error: '' . $e->getMessage()); // To only show error
}
function somethingIsOK() {
return mt_rand(0, 10) < 5;
}
?>
HTML:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>PHP Error test</title>
<style type="text/css">
body {
background: #eee;
text-align: center
}
#content {
padding: 60px
}
#header {
padding: 30px;
background: #fff
}
#footer {
padding: 10px;
background: #ddd
}
</style>
</head>
<body>
<div id="header">Header</div>
<div id="content">
<?php echo implode(''<br />'', $output); ?>
</div>
<div id="footer">Footer</div>
</body>
</html>
Referencias