web-dev-qa-db-ja.com

死のPHPホワイトスクリーン

PHPに戻り始めた今、最初にそれを放棄した理由を思い出し始めました。現時点で私のプレート上で最も厄介なのは、「PHPの死の白い画面」と呼んでいるものです。 PHPが構文などに起因する致命的なエラーを受け取った場合、実際にブラウザに何も送信せずに常に死んでしまうようです。以下を.htaccessに追加しましたが、ほとんどの場合機能するようですが、これらの場合は機能しません。

php_value display_errors 1
php_value display_startup_errors 1
php_value error_reporting 2147483647 # E_ALL

何か不足していますか?現時点では、コードの数行ごとに更新する必要があるように感じています。ミスを犯し、その小さなミスを追跡するために多くのページを検索する必要があります...

EDIT:たとえば、次の2行のコードを考えます。

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

1つ目は死の白い画面(つまり、ブラウザに何も印刷されない)を表示し、2つ目は喜んで実行します。

126

エラーと警告は通常、php.iniの設定に応じて....\logs\php_error.logまたは....\logs\Apache_error.logに表示されます。

また、有用なエラーは多くの場合ブラウザに送信されますが、有効なHTMLではないため表示されません。

したがって、ログファイルを"tail -f "し、空白の画面が表示された場合は、IEの[表示]-> [ソース]メニューオプションを使用して生の出力を表示します。

59
James Anderson

次のコードはすべてのエラーを表示するはずです:

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

?>

このコードで空白ページを生成する唯一の方法は、シャットダウンハンドラーでエラーが発生した場合です。これをテストせずに自分のcmsからコピーして貼り付けましたが、動作するはずです。

169
m4dm4x1337

私は常にphpスクリプトの最上部でこの構文を使用しています。

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

フックを登録して、最後のエラーまたは警告を表示することができます。

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

register_shutdown_function('shutdown');

このコードをindex.phpの先頭に追加すると、問題のデバッグに役立ちます。

24

これは、ロードされた構成とランタイム構成の問題です

compileまたはparsingのステップ中に構文エラーまたは解析エラーが発生することを認識することが重要です。つまり、PHPが始まる前に保釈されます。コードを実行する機会。したがって、実行時にPHPのdisplay_errors構成を変更する場合(これには、コードでini_setを使用することから、ランタイム構成ファイルである.htaccessを使用することまで含まれます)、デフォルトのloaded構成設定が機能しています。

開発時に常にWSODを回避する方法

WSODを回避するには、読み込まれた設定ファイルdisplay_errors onであり、error_reporting-1に設定されていることを確認する必要があります(thisこれは、実行しているPHPのバージョンに関係なくすべてのビットがオンになることを保証するため、同等のE_ALLです)。 E_ALLの定数値は、PHPの異なるバージョン間で変更される可能性があるため、ハードコードしないでください。

ロードされた構成は、ロードされたphp.iniファイル、またはApache.confまたはhttpd.confまたはvirtualhostファイルのいずれかです。これらのファイルは、起動段階(たとえば、Apache httpdまたはphp-fpmを最初に起動したとき)で1回だけ読み込まれ、ランタイム構成の変更によってのみ上書きされます。ロードされた構成ファイルでdisplay_errors = 1およびerror_reporting = -1を確認すると、前に発生した構文エラーまたは解析エラーに関係なく、WSODが表示されなくなります。 ini_set('display_errors', 1);error_reporting(E_ALL);などの実行時の変更を行うことができます。

(php.ini)に読み込まれた構成ファイルを見つける方法

ロードされた設定ファイルを見つけるには、次のコードのみで新しいPHPファイルを作成してください...

<?php
phpinfo();

次に、ブラウザをそこに向けて、読み込まれた設定ファイル解析された追加の.iniファイルを見てください。これらは通常、phpinfo()の上部にあり、ロードされたすべての構成ファイルへのパス。

ファイルの代わりに(none)が表示される場合、構成ファイル(php.ini)パスにphp.iniがないことを意味します。 ここからPHPにバンドルされている標準のphp.iniをダウンロード して、それをphp.iniとして設定ファイルパスにコピーしてから、phpユーザーに十分な読み取り権限があることを確認してくださいそのファイルから。ロードするには、httpdまたはphp-fpmを再起動する必要があります。これは、PHPにバンドルされているdevelopmentphp.iniファイルです。ソース。そのため、本番環境では使用しないでください!


本番環境でこれをしないでください

これは、開発中のWSODを回避する最良の方法です。 PHPスクリプトの先頭にini_set('display_errors', 1);またはerror_reporting(E_ALL);を配置すること、またはここで行ったように.htaccessを使用することを提案する人は、構文がWSODを避けるのに役立ちません。または、ロードされた構成ファイルのdisplay_errorsがオフになっている場合、解析エラーが発生します(ここでの場合のように)。

多くの人々(およびPHPの標準インストール)は、デフォルトでdisplay_errorsがオフになっているproduction-iniファイルを使用します。これは通常、ここで経験したのと同じフラストレーションをもたらします。 PHPは起動時に既にオフになっているため、構文エラーまたは解析エラーが発生し、出力するものが何もない状態でベイルします。 PHPスクリプトの先頭にあるini_set('display_errors',1);はそれを避けるべきであると期待しますが、PHPがコードを解析できなくても問題はありません。ランタイムに到達したことはありません。

18
Sherif

Dunnoが役立つ場合は、PHPプロジェクト用の標準構成ファイルの一部を以下に示します。私は自分のサーバーでさえもApacheの設定にあまり依存しない傾向があります。

エラーが消える問題は一度もありませんので、おそらくここで何かがあなたにアイデアを与えるでしょう。

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

php.iniを開き、次のように設定されていることを確認します。

display_errors = On

サーバーを再起動します。

6
user577803

Nginxを使用し、<?php echo 123;を含むファイルでも白い画面が表示される場合。私の場合、nginx設定ファイルのPHPにこの必須オプションがありませんでした。

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

このオプションはfastcgi_paramsファイルになかったので、PHPは機能せず、ログにエラーはありませんでした。

3
AVKurov

実際のphpファイルでエラー報告レベルを設定してみてください。または、他の人が示唆しているように、サーバーの設定を確認してください-php.iniにあるものか、ホストに関する制限がある可能性があります。 .htaccessだけに依存しないでください。また、トラブルシューティングの際に、怪しいと思われる変数をprint_rします。

2
Lewis LaCook

PHPは実際に.htaccessから 'display_errors'設定を選択していますか? phpinfo()関数の出力を確認して確認してください。

また、「@」を使用していないことを確認する必要があります。「@ include ...」または「@some_function(...)」を使用している場合、エラーを抑制できます。スタックトレースのどこか。

2
too much php

php -f filename.phpのように、ターミナル(コマンドライン)でファイルを実行することもできます。

これによりコードが実行され、error.logにエラーが表示された場合でも同じ出力が得られます。エラーと行番号に言及しています。

1
Aamnah

コードで@inexistent_function_call();を使用すると、インタープリターが静かに停止し、スクリプトの解析が中止されます。無効な関数をチェックし、エラー抑制演算子(@ char)を使用しないようにしてください。

1
Quamis

fastcgi_paramsまたはfastcgi.conf構成ファイルがサーバー構成に適切に含まれていない場合にも、このようなエラーが発生しました。だから私にとっての修正はばかげていた:

include /etc/nginx/fastcgi_params;

それを見つけるためにhourを手に入れました...

1
anarcat

一部のアプリケーションは、次のようなものを呼び出すことで、これらの命令自体を処理します。

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

したがって、.htaccess設定をオーバーライドします。

1
Denegen