web-dev-qa-db-de.com

PHP weißer Bildschirm des Todes

Jetzt, wo ich anfange, wieder in PHP einzusteigen, beginne ich mich zu erinnern, warum ich es überhaupt aufgegeben habe. Das nervigste auf meinem Teller ist momentan, was ich als "PHPs weißer Bildschirm des Todes" bezeichne. Wenn PHP einen schwerwiegenden Fehler aufgrund der Syntax oder was auch immer bekommt, scheint es immer zu sterben, ohne etwas an den Browser zu senden. Ich habe Folgendes zu meinem .htaccess Hinzugefügt. , und es scheint die meiste Zeit zu funktionieren, aber in diesen Fällen funktioniert es nicht.

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

Vermisse ich etwas? Im Moment habe ich das Gefühl, ich muss alle paar Zeilen Code, die ich schreibe, auf "Aktualisieren" klicken, damit ich einen Fehler mache und viele Seiten durchsuchen muss, um diesen einen kleinen Fehler aufzuspüren ...

EDIT: Beispiel mit den folgenden zwei Codezeilen:

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

Der erste zeigt den weißen Bildschirm des Todes (dh, es wird überhaupt nichts im Browser gedruckt), während der zweite zufriedenstellend ausgeführt wird.

126

Fehler und Warnungen erscheinen normalerweise in ....\logs\php_error.log oder ....\logs\Apache_error.log abhängig von deinen php.ini Einstellungen.

Auch nützliche Fehler werden oft an den Browser gerichtet, aber da sie kein gültiges HTML sind, werden sie nicht angezeigt.

So "tail -f "Ihre Protokolldateien und wenn Sie einen leeren Bildschirm erhalten, verwenden Sie die Menüoptionen" Ansicht "->" Quelle ", um die Rohausgabe anzuzeigen.

59
James Anderson

Der folgende Code sollte alle Fehler anzeigen:

<?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

?>

Die einzige Möglichkeit, mit diesem Code eine leere Seite zu generieren, besteht darin, dass im Shutdown-Handler ein Fehler auftritt. Ich habe das von meinem eigenen cms kopiert und eingefügt, ohne es zu testen, aber ich bin sicher, dass es funktioniert.

169
m4dm4x1337

Ich benutze diese Syntax immer ganz oben im PHP-Skript.

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

Es ist möglich, einen Haken zu registrieren, um den letzten Fehler oder die letzte Warnung sichtbar zu machen.

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

register_shutdown_function('shutdown');

indem Sie diesen Code an den Anfang Ihrer index.php-Datei setzen, können Sie die Probleme leichter beheben.

24

Dies ist ein Problem der geladenen vs. Laufzeitkonfiguration

Es ist wichtig zu wissen, dass ein Syntax- oder Analysefehler während des Kompilierungs- oder Parsing-Schritts auftritt, was bedeutet, dass PHP wird abgehängt, bevor es überhaupt die Möglichkeit gab, irgendeinen Ihrer Codes auszuführen. Wenn Sie also die PHP-Konfiguration display_errors Während der Laufzeit ändern (dazu gehört die Verwendung von ini_set In Ihrem Code bis hin zur Verwendung von .htaccess, einer Laufzeitkonfigurationsdatei), ist nur die Standardkonfiguration geladene Konfigurationseinstellungen sind im Spiel.

So vermeiden Sie WSOD in der Entwicklung immer

Um einen WSOD zu vermeiden, sollten Sie sicherstellen, dass in Ihrer geladenen Konfigurationsdatei display_errors Aktiviert und error_reporting Auf -1 Gesetzt ist ( Dies ist das Äquivalent zu E_ALL, da es sicherstellt, dass alle Bits aktiviert sind, unabhängig davon, welche Version von PHP Sie ausführen). Codieren Sie den konstanten Wert von E_ALL nicht hart, da sich dieser Wert zwischen verschiedenen PHP-Versionen ändern kann.

Die geladene Konfiguration ist entweder Ihre geladene php.ini - oder Ihre Apache.conf - oder httpd.conf - oder VirtualHost-Datei. Diese Dateien werden während der Startphase (zum Beispiel beim ersten Start von Apache httpd oder php-fpm) nur einmal gelesen und nur von Änderungen der Laufzeitkonfiguration überschrieben. Wenn Sie sicherstellen, dass display_errors = 1 Und error_reporting = -1 In Ihrer geladenen Konfigurationsdatei enthalten sind, wird unabhängig davon niemals ein [~ # ~] wsod [~ # ~] angezeigt Syntax- oder Analysefehler, die auftreten, bevor eine Laufzeitänderung wie ini_set('display_errors', 1); oder error_reporting(E_ALL); stattfinden kann.

So finden Sie Ihre (php.ini) geladenen Konfigurationsdateien

Um Ihre geladene (n) Konfigurationsdatei (en) zu finden, erstellen Sie einfach eine neue PHP Datei mit nur dem folgenden Code ...

<?php
phpinfo();

Zeigen Sie dann mit Ihrem Browser auf Geladene Konfigurationsdatei und Zusätzliche geparste INI-Dateien , die sich normalerweise am oberen Rand befinden phpinfo() und enthält den absoluten Pfad zu allen geladenen Konfigurationsdateien.

Wenn Sie anstelle der Datei (none) Sehen, bedeutet dies, dass Sie keine php.ini im Konfigurationsdateipfad (php.ini) haben . Sie können also Laden Sie die mit PHP mitgelieferte php.ini von hier herunter und kopieren Sie diese in Ihren Konfigurationsdateipfad als php.ini. Stellen Sie dann sicher, dass Ihr PHP-Benutzer über ausreichende Leserechte verfügt aus dieser Datei. Sie müssen httpd oder php-fpm neu starten, um es zu laden. Denken Sie daran, dies ist die Entwicklung php.ini-Datei, die mit der Quelle PHP mitgeliefert wird. Also bitte nicht in der Produktion verwenden!


Mach das einfach nicht in der Produktion

Dies ist wirklich der beste Weg, um ein WSOD in der Entwicklung zu vermeiden. Wer vorschlägt, dass Sie ini_set('display_errors', 1); oder error_reporting(E_ALL); am Anfang Ihres PHP Skripts einfügen oder .htaccess wie hier verwenden, kann a nicht vermeiden WSOD, wenn ein Syntax- oder Analysefehler auftritt (wie in Ihrem Fall hier), wenn in Ihrer geladenen Konfigurationsdatei display_errors Deaktiviert ist.

Viele Benutzer (und Standardinstallationen von PHP) verwenden eine Production-Ini-Datei, deren display_errors - Funktion standardmäßig deaktiviert ist. Dies führt in der Regel zu derselben Frustration, die Sie hier erlebt haben. Da PHP es beim Start bereits deaktiviert hat, dann auf einen Syntax- oder Analysefehler stößt und keine Ausgabe mehr möglich ist. Sie erwarten, dass Ihr ini_set('display_errors',1); am Anfang Ihres PHP Skripts dies hätte vermeiden sollen, aber es spielt keine Rolle, ob PHP Ihren Code aus folgenden Gründen nicht analysieren kann es wird nie die Laufzeit erreicht haben.

18
Sherif

Keine Ahnung, ob es hilft, aber hier ist ein Teil meiner Standard-Konfigurationsdatei für PHP-Projekte. Ich neige dazu, nicht zu sehr von den Apache-Konfigurationen abhängig zu sein, auch nicht von meinem eigenen Server.

Ich habe nie das Problem des verschwindenden Fehlers. Vielleicht gibt Ihnen hier etwas eine Idee.

Bearbeitet, um APPLICATON_LIVE anzuzeigen

/*
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

öffne deine php.ini und stelle sicher, dass sie auf:

display_errors = On

starten Sie Ihren Server neu.

6
user577803

Für diejenigen, die Nginx verwenden und einen weißen Bildschirm haben, auch für Dateien mit <?php echo 123;. In meinem Fall hatte ich diese erforderliche Option nicht für PHP in der Nginx-Konfigurationsdatei:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Diese Option befand sich nicht in der Datei fastcgi_params, daher funktionierte PHP nicht und es gab keine Fehler in den Protokollen.

3
AVKurov

Versuchen Sie, Ihre Fehlerberichterstattungsstufe in Ihren tatsächlichen PHP-Dateien festzulegen. Oder, wie andere vorgeschlagen haben, überprüfen Sie Ihre Servereinstellungen - es könnte etwas in der php.ini oder eine Einschränkung in Bezug auf Ihren Host sein. Verlassen Sie sich nicht nur auf .htaccess. Außerdem sollten Sie bei der Fehlerbehebung alle Variablen drucken, die Sie für faul halten.

2
Lewis LaCook

Sind Sie sicher, dass PHP übernimmt tatsächlich die Einstellung 'display_errors' Von .htaccess? Überprüfen Sie die Ausgabe der Funktion phpinfo(), um sicherzustellen, dass.

Außerdem sollten Sie überprüfen, ob Sie "@" Nicht verwendet haben. Wenn Sie "@include ..." oder "@some_function (...)" verwendet haben, werden Ihre Fehler möglicherweise stummgeschaltet. Irgendwo in der Stapelspur.

2
too much php

Sie können die Datei auch wie folgt im Terminal (Befehlszeile) ausführen: php -f filename.php.

Dadurch wird Ihr Code ausgeführt und Sie erhalten die gleiche Ausgabe, falls Fehler auftreten, die im error.log. Es erwähnt den Fehler und die Zeilennummer.

1
Aamnah

wenn Sie in Ihrem Code @inexistent_function_call(); verwenden, stirbt der Interpreter im Hintergrund und bricht die Skriptanalyse ab. Sie sollten nach ungültigen Funktionen suchen und versuchen, den fehlersichernden Operator (@ char) nicht zu verwenden.

1
Quamis

Ich habe auch solche Fehler gesehen, wenn die fastcgi_params oder fastcgi.conf Konfigurationsdatei ist nicht ordnungsgemäß in der Serverkonfiguration enthalten. Also war die Lösung für mich eine dumme:

include /etc/nginx/fastcgi_params;

Ich habe eine Stunde gebraucht, um das herauszufinden ...

1
anarcat

Einige Anwendungen verarbeiten diese Anweisungen selbst, indem sie Folgendes aufrufen:

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

Und damit überschreiben Sie Ihre .htaccess-Einstellungen.

1
Denegen