web-dev-qa-db-fra.com

Écran blanc de la mort PHP

Maintenant que je commence à revenir à PHP, je commence à me rappeler pourquoi je l'ai abandonné en premier lieu. La chose la plus agaçante dans mon assiette à l’heure actuelle est ce que j’ai appelé "l’écran blanc de la mort de PHP". Lorsque PHP obtient une erreur fatale en raison de la syntaxe ou autre, il semble qu'il mourra toujours sans envoyer quoi que ce soit au navigateur. J'ai ajouté ce qui suit à mon .htaccess, et cela semble fonctionner la plupart du temps, mais cela ne fonctionne pas dans ces cas-là.

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

Est-ce que je manque quelque chose? Pour le moment, j’ai besoin d’actualiser toutes les quelques lignes de code que j’écris pour éviter de commettre une erreur et de devoir parcourir plusieurs pages en essayant de retrouver cette petite erreur que j’ai commise ...

EDIT: Par exemple, étant donné les deux lignes de code ci-dessous:

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

Le premier présentera l’écran blanc de la mort (c’est-à-dire que rien ne sera imprimé sur le navigateur), tandis que le second s’exécutera avec bonheur.

126
Matthew Scharley

Les erreurs et les avertissements apparaissent généralement dans ....\logs\php_error.log ou ....\logs\Apache_error.log en fonction de vos paramètres php.ini.

De plus, les erreurs utiles sont souvent dirigées vers le navigateur, mais comme elles ne sont pas du code HTML valide, elles ne sont pas affichées.

Alors "tail -f "vos fichiers journaux et lorsque vous obtenez un écran vide, utilisez les options du menu" Voir "->" Source "d'IE pour afficher le résultat brut.

59
James Anderson

Le code suivant devrait afficher toutes les erreurs:

<?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(!@is_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 seule façon de générer une page vierge avec ce code est lorsque vous avez une erreur dans le gestionnaire d'arrêt. Je l'ai copié et collé à partir de mes propres cms sans le tester, mais je suis sûr que cela fonctionne.

169
m4dm4x1337

J'utilise toujours cette syntaxe tout en haut du script php.

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

Il est possible d’enregistrer un hook pour rendre visible la dernière erreur ou le dernier avertissement.

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

register_shutdown_function('shutdown');

l'ajout de ce code au début de index.php vous aidera à résoudre les problèmes.

24
Eduardo Oliveira

C'est un problème de configuration chargée par rapport à l'exécution

Il est important de reconnaître qu'une erreur de syntaxe ou une erreur d'analyse se produit lors de l'étape compile ou analyse , ce qui signifie que PHP sera mis à jour avant même qu'il n'ait eu l'occasion d'exécuter aucun de vos codes. Donc, si vous modifiez la configuration de PHP display_errors À l'exécution, (cela inclut quoi que ce soit d'utiliser ini_set Dans votre code pour utiliser .htaccess, qui est un fichier de configuration à l'exécution), seules les valeurs par défaut chargé les paramètres de configuration sont en cours.

Comment toujours éviter les WSOD en développement

Pour éviter un WSOD, vous voulez vous assurer que votre fichier de configuration chargé a display_errors Activé et que error_reporting Est défini sur -1 ( Ceci est l'équivalent E_ALL car il garantit que tous les bits sont activés quelle que soit la version de PHP que vous utilisez). Ne codez pas en dur la valeur constante de E_ALL , car cette valeur est sujette à changement entre les différentes versions de PHP.

La configuration chargée est soit votre fichier chargé php.ini, Soit votre fichier Apache.conf Ou httpd.conf Ou virtualhost. Ces fichiers ne sont lus qu'une fois lors de la phase de démarrage (lorsque vous démarrez Apache pour la première fois httpd ou php-fpm, par exemple) et ne sont remplacés que par les modifications apportées à la configuration de l'exécution. Assurez-vous que display_errors = 1 Et error_reporting = -1 Dans votre fichier de configuration chargé garantissent que vous ne verrez jamais un [~ ~ ~] wsod [~ # ~], quelle que soit la syntaxe ou erreur d'analyse qui se produit avant qu'un changement d'exécution tel que ini_set('display_errors', 1); ou error_reporting(E_ALL); puisse avoir lieu.

Comment trouver vos fichiers de configuration (php.ini) chargés

Pour localiser vos fichiers de configuration chargés, créez simplement un nouveau fichier PHP) avec uniquement le code suivant ...

<?php
phpinfo();

Ensuite, pointez votre navigateur et regardez Fichier de configuration chargé et Fichiers .ini supplémentaires analysés , qui se trouvent généralement en haut de votre phpinfo() et inclura le chemin absolu de tous vos fichiers de configuration chargés.

Si vous voyez (none) À la place du fichier, cela signifie que vous n'avez pas de php.ini dans Fichier de configuration (php.ini) Path . Donc vous pouvez télécharger le stock php.ini fourni avec PHP d'ici et le copier dans votre chemin d'accès au fichier de configuration en tant que php.ini, puis assurez-vous que votre utilisateur php en a assez Vous devez redémarrer httpd ou php-fpm pour le charger. Rappelez-vous qu’il s’agit du fichier development ​​php.ini fourni avec PHP source, ne l'utilisez donc pas en production!


Ne fais pas ça en production

C'est vraiment le meilleur moyen d'éviter un WSOD en développement. Toute personne suggérant de placer ini_set('display_errors', 1); ou error_reporting(E_ALL); en haut de votre script PHP ou en utilisant .htaccess comme vous l'avez fait ici) ne vous aidera pas vous évitez un WSOD lorsqu'une erreur de syntaxe ou d'analyse se produit (comme dans votre cas ici) si votre fichier de configuration chargé a display_errors désactivé.

Un grand nombre de personnes (et d'installations standard de PHP) utiliseront un fichier de production ini dont display_errors Est désactivé par défaut, ce qui engendre généralement la même frustration que celle que vous avez connue ici. Parce que PHP l'a déjà désactivé au démarrage, puis rencontre une erreur de syntaxe ou d'analyse, et ne contient rien à afficher. Vous vous attendez à ce que votre ini_set('display_errors',1); en haut de votre PHP script aurait dû éviter cela, mais cela n'aura pas d'importance si PHP ne peut pas analyser votre code car il n'aura jamais atteint le runtime.

18
Sherif

Je ne sais pas si cela vous aidera, mais voici un extrait de mon fichier de configuration standard pour les projets php. J'ai tendance à ne pas trop dépendre de la configuration d'Apache, même de mon propre serveur.

Je n'ai jamais le problème d'erreur qui disparaît, alors peut-être que quelque chose ici va vous donner une idée.

Modifié pour afficher 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>");
}
15
Eli

ouvrez votre php.ini, assurez-vous qu'il est réglé sur:

display_errors = On

redémarrez votre serveur.

6
user577803

Pour ceux qui utilisent nginx et ont un écran blanc même pour les fichiers avec <?php echo 123;. Dans mon cas, je n'avais pas cette option requise pour PHP dans le fichier de configuration nginx:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Cette option n'était pas dans le fichier fastcgi_params, donc PHP ne fonctionnait pas et il n'y avait aucune erreur dans les journaux.

3
AVKurov

Essayez de définir votre niveau de rapport d'erreur dans vos fichiers php réels. Ou, comme d'autres l'ont suggéré, vérifiez les paramètres de votre serveur - cela pourrait être quelque chose dans php.ini, ou une restriction en ce qui concerne votre hôte. Ne comptez pas uniquement sur .htaccess. En outre, lors du dépannage, print_r toute variable suspecte.

2
Lewis LaCook

Êtes-vous sûr que PHP récupère le paramètre 'display_errors' De .htaccess? Vérifiez le résultat de la fonction phpinfo() pour vous en assurer.

En outre, vous devez vous assurer que vous n'avez pas utilisé '@', Cela pourrait faire taire vos erreurs si vous avez utilisé '@include ...' ou '@some_function (...)' , quelque part en haut de la trace de la pile.

2
too much php

Vous pouvez également exécuter le fichier dans le terminal (ligne de commande) comme suit: php -f filename.php.

Ceci exécute votre code et vous donne le même résultat en cas d'erreurs que vous verriez dans le error.log. Il mentionne l'erreur et le numéro de ligne.

1
Aamnah

si vous utilisez @inexistent_function_call(); dans votre code, l’interprète mourra discrètement et abandonnera l’analyse du script. Vous devez vérifier les fonctions non valides et essayer de ne pas utiliser l'opérateur de suppression d'erreur (le caractère @)

1
Quamis

J'ai aussi vu de telles erreurs quand le fastcgi_params ou fastcgi.conf Le fichier de configuration n’est pas correctement inclus dans la configuration du serveur. Donc, la solution pour moi était un idiot:

include /etc/nginx/fastcgi_params;

Il m'a fallu une heure pour le savoir ...

1
anarcat

Certaines applications gèrent ces instructions elles-mêmes, en appelant quelque chose comme ceci:

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

Et par-dessus vos paramètres .htaccess.

1
Denegen