Pantalla blanca de la muerte de PHP




pantalla blanca wordpress (12)

Ahora que estoy empezando a volver a PHP, estoy empezando a recordar por qué lo abandoné en primer lugar. Lo más molesto de mi plato en este momento es lo que he llegado a denominar "pantalla blanca de la muerte de PHP". Cuando PHP obtiene un error fatal debido a la sintaxis o lo que sea, parece que siempre morirá sin enviar nada al navegador. He agregado lo siguiente a mi .htaccess , y parece funcionar la mayor parte del tiempo, pero no funciona en estos casos.

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

¿Me estoy perdiendo de algo? Por el momento, siento que necesito presionar Actualizar cada pocas líneas de código que escribo, para no cometer un error y tener que buscar en muchas páginas tratando de rastrear ese pequeño error que cometí ...

EDITAR: Por ejemplo, dadas las dos líneas de código a continuación:

$foo = array(':language' => $languageId;
$foo = array(':language' => $languageId);

El primero exhibirá la pantalla blanca de la muerte (es decir, nada impreso en el navegador), mientras que el segundo se ejecutará felizmente.


¿Estás seguro de que PHP está realmente seleccionando la configuración ' display_errors ' de .htaccess? Compruebe la salida de la función phpinfo() para asegurarse.

Además, debe verificar que no haya utilizado ' @ ', podría silenciar sus errores si ha utilizado '@include ...' o '@some_function (...)', en algún lugar de la pila rastro.


No sé si será útil, pero aquí hay una parte de mi archivo de configuración estándar para proyectos de PHP. Tiendo a no depender demasiado de las configuraciones de apache incluso en mi propio servidor.

Nunca tengo el problema de error que desaparece, así que quizás algo aquí te dará una idea.

Editado para mostrar APPLICATON_LIVE

/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment.  It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/

if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
    define('APPLICATION_LIVE', false);
} else {
    die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
    // Log or take other appropriate action.
}


/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging.  Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");

if ( ! APPLICATION_LIVE ) {
    // A few changes to error handling for development.
    // We will want errors to be visible during development.
    ini_set ( "display_errors", "1");
    ini_set ( "display_startup_errors", "1");
    ini_set ( "html_errors", "1");
    ini_set ( "docref_root", "http://www.php.net/");
    ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
    ini_set ( "error_append_string", "</div>");
}

Intente configurar su nivel de informe de error en sus archivos php reales. O, como otros han sugerido, verifique la configuración de su servidor: podría tratarse de algo en php.ini o de alguna restricción con respecto a su host. No confíes solo en .htaccess. Además, cuando resuelves problemas, imprime cualquier variable que puedas considerar sospechosa.


Algunas aplicaciones sí manejan estas instrucciones, llamando a algo como esto:

error_reporting(E_ALL & ~E_DEPRECATED); or error_reporting(0);

Y anulando así su configuración de .htaccess.


Es posible registrar un gancho para hacer visible el último error o advertencia.

function shutdown(){
  var_dump(error_get_last());
}

register_shutdown_function('shutdown');

agregar este código al comienzo de su index.php lo ayudará a depurar los problemas.


Para aquellos que usan nginx y tienen una pantalla en blanco incluso para el archivo con <?php echo 123; . En mi caso, no tenía esta opción requerida para PHP en el archivo de configuración nginx:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Esta opción no estaba en el archivo fastcgi_params, por lo que PHP no funcionó y no hubo ningún error en los registros.


El siguiente código debería mostrar todos los errores:

<?php

// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);

// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);

// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
    if(@is_array($error = @error_get_last()))
    {
        return(@call_user_func_array('ErrorHandler', $error));
    };

    return(TRUE);
};

register_shutdown_function('ShutdownHandler');

// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
    $_ERRORS = Array(
        0x0001 => 'E_ERROR',
        0x0002 => 'E_WARNING',
        0x0004 => 'E_PARSE',
        0x0008 => 'E_NOTICE',
        0x0010 => 'E_CORE_ERROR',
        0x0020 => 'E_CORE_WARNING',
        0x0040 => 'E_COMPILE_ERROR',
        0x0080 => 'E_COMPILE_WARNING',
        0x0100 => 'E_USER_ERROR',
        0x0200 => 'E_USER_WARNING',
        0x0400 => 'E_USER_NOTICE',
        0x0800 => 'E_STRICT',
        0x1000 => 'E_RECOVERABLE_ERROR',
        0x2000 => 'E_DEPRECATED',
        0x4000 => 'E_USER_DEPRECATED'
    );

    if([email protected]_string($name = @array_search($type, @array_flip($_ERRORS))))
    {
        $name = 'E_UNKNOWN';
    };

    return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message)));
};

$old_error_handler = set_error_handler("ErrorHandler");

// other php code

?>

La única forma de generar una página en blanco con este código es cuando tiene un error en el controlador de apagado. Copié y pegué esto desde mi propio cms sin probarlo, pero estoy seguro de que funciona.


También puede ejecutar el archivo en la Terminal (línea de comando) de la siguiente manera: php -f filename.php .

Esto ejecuta su código y le da el mismo resultado en caso de cualquier error que pueda ver en el error.log . Menciona el error y el número de línea.


Siempre uso esta sintaxis en la parte superior del script php.

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On');  //On or Off

usando @inexistent_function_call(); en su código hará que el intepretador muera silenciosamente y abortará el análisis del script. Debería comprobar si hay funciones no válidas y tratar de no usar el operador de supresión de errores (el @ char)


Este es un problema de configuración cargada vs. tiempo de ejecución

Es importante reconocer que un error de sintaxis o un error de análisis ocurre durante el paso de compilación o análisis sintáctico , lo que significa que PHP se fianza antes incluso de que haya tenido la oportunidad de ejecutar cualquiera de sus códigos. Entonces, si está modificando la configuración display_errors de PHP durante el tiempo de ejecución (esto incluye desde usar ini_set en su código hasta usar .htaccess, que es un archivo de configuración en tiempo de ejecución), entonces solo están en juego las configuraciones predeterminadas de configuración cargada .

Cómo evitar siempre WSOD en desarrollo

Para evitar un WSOD, debe asegurarse de que el archivo de configuración cargado tenga display_errors on y error_reporting establecidos en -1 ( este es el E_ALL equivalente porque asegura que todos los bits estén activados independientemente de la versión de PHP que esté ejecutando ). No codifique el valor constante de E_ALL, ya que ese valor está sujeto a cambios entre las diferentes versiones de PHP.

La configuración cargada es su archivo php.ini cargado o su archivo apache.conf o httpd.conf o virtualhost. Esos archivos solo se leen una vez durante la etapa de inicio (cuando se inicia Apache httpd o php-fpm, por ejemplo) y solo se reemplazan por los cambios en la configuración del tiempo de ejecución. Asegurarse de que display_errors = 1 y error_reporting = -1 en su archivo de configuración cargado asegura que nunca verá un WSOD independientemente de la sintaxis o el error de análisis que ocurra antes de un cambio de tiempo de ejecución como ini_set('display_errors', 1); o error_reporting(E_ALL); puede tomar lugar.

Cómo encontrar sus archivos de configuración cargados (php.ini)

Para ubicar los archivos de configuración cargados, solo cree un nuevo archivo PHP con solo el siguiente código ...

<?php
phpinfo();

A continuación, dirija su navegador hacia allí y observe el archivo de configuración cargada y los archivos .ini adicionales analizados , que generalmente se encuentran en la parte superior de su phpinfo() e incluirán la ruta absoluta a todos sus archivos de configuración cargados.

Si ve (none) lugar del archivo, eso significa que no tiene un php.ini en la Ruta del archivo de configuración (php.ini) . De modo que puede descargar el stock php.ini incluido con PHP desde aquí y copiarlo en su ruta de archivo de configuración como php.ini, luego asegúrese de que su usuario de php tenga los permisos suficientes para leer desde ese archivo. Tendrá que reiniciar httpd o php-fpm para cargarlo. Recuerde, este es el archivo php.ini de desarrollo que viene incluido con el código PHP. ¡Por favor no lo use en producción!

Simplemente no hagas esto en producción

Esta es realmente la mejor manera de evitar un WSOD en desarrollo. Alguien sugiriendo que ponga ini_set('display_errors', 1); o error_reporting(E_ALL); en la parte superior de su script PHP o utilizando .htaccess como lo hizo aquí, no lo ayudará a evitar un WSOD cuando se produce un error de sintaxis o análisis (como en su caso aquí) si el archivo de configuración cargado tiene display_errors desactivado.

Muchas personas (y las instalaciones en existencia de PHP) usarán un archivo de producción en ini que tiene display_errors desactivado de manera predeterminada, lo que generalmente resulta en la misma frustración que ha experimentado aquí. Debido a que PHP ya lo tiene apagado cuando se inicia, entonces encuentra una sintaxis o un error de análisis, y lo libera con nada para producir. Esperas que tu ini_set('display_errors',1); en la parte superior de su script PHP debería haber evitado eso, pero no importará si PHP no puede analizar su código porque nunca habrá llegado al tiempo de ejecución.


Si el error está en el código PHP, puede usar la función error_reporting () dentro de su código para establecerlo en el informe.

Sin embargo, esto no soluciona la situación cuando PHP se cuelga. La información sobre eso solo está disponible en los registros del servidor. Tal vez no tienes acceso a esos, pero muchos proveedores de hosting con los que he trabajado tienen alguna forma de permitirte acceder a ellos. Por ejemplo, el enfoque que más me gusta es que crea el archivo error_log en el directorio actual donde reside .php. Intente buscar allí o contacte a su proveedor de alojamiento web al respecto.





wsod