以下のように、特定の関数の前で@
を使用したことがあります。
$fileHandle = @fopen($fileName, $writeAttributes);
この記号の用途は何ですか?
エラーメッセージを抑制します - PHPマニュアルの エラー制御演算子 を参照してください。
エラーを抑制します。
マニュアルの エラー制御演算子 を参照してください。
PHPは1つのエラー制御演算子、アットマーク(@)をサポートしています。 PHPの式の前に付けると、その式によって生成される可能性のあるエラーメッセージはすべて無視されます。
set_error_handler() を使ってカスタムエラーハンドラ関数を設定した場合、それはまだ呼び出されますが、このカスタムエラーハンドラは を呼び出すことができます。 error_reporting() は、エラーを引き起こした呼び出しの前に@ ...が付いたときに0を返します。
@
シンボルは、 エラー制御演算子 です。 「沈黙」または「終了」オペレータ)。これはPHPに、関連する式によって生成されたエラーメッセージ(notice、warning、fatalなど)を抑制させます。これは単項演算子のように機能します。たとえば、優先順位と結合性があります。以下はその例です。
@echo 1 / 0;
// generates "Parse error: syntax error, unexpected T_ECHO" since
// echo is not an expression
echo @(1 / 0);
// suppressed "Warning: Division by zero"
@$i / 0;
// suppressed "Notice: Undefined variable: i"
// displayed "Warning: Division by zero"
@($i / 0);
// suppressed "Notice: Undefined variable: i"
// suppressed "Warning: Division by zero"
$c = @$_POST["a"] + @$_POST["b"];
// suppressed "Notice: Undefined index: a"
// suppressed "Notice: Undefined index: b"
$c = @foobar();
echo "Script was not terminated";
// suppressed "Fatal error: Call to undefined function foobar()"
// however, PHP did not "ignore" the error and terminated the
// script because the error was "fatal"
標準のPHPエラーハンドラの代わりにカスタムエラーハンドラを使用した場合、正確にはどうなりますか。
Set_error_handler()でカスタムエラーハンドラ関数を設定した場合でもそれは呼び出されますが、このカスタムエラーハンドラはerror_reporting()を呼び出すことができます。 。
これは、次のコード例に示されています。
function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
echo "[bad_error_handler]: $errstr";
return true;
}
set_error_handler("bad_error_handler");
echo @(1 / 0);
// prints "[bad_error_handler]: Division by zero"
エラーハンドラは@
シンボルが有効であるかどうかをチェックしませんでした。このマニュアルは以下のことを示唆しています。
function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
if(error_reporting() !== 0) {
echo "[better_error_handler]: $errstr";
}
// take appropriate action
return true;
}
また、エラーが隠されていても、カスタムエラーハンドラ(set_error_handler
で設定)は実行されます。
@
演算子は、通知、警告、さらには重大なエラーを含む、PHPのすべてのエラーを抑制します。
しかし:どうぞ、@
演算子を使わないでくださいまったく
どうしてですか?
エラー抑制のために@
演算子を使用した場合、エラーが発生したときにどこから開始するかについての手がかりがまったくないためです。私はすでに何人かの開発者がかなり頻繁に@
演算子を使用していたレガシーコードで「楽しい」をしました。特にファイル操作、ネットワークコールなどの場合。これらはエラーが発生したときに範囲外になることがあるため、多くの開発者が@
演算子の使用を推奨するすべてのケースです(たとえば3rdparty APIにアクセスできないなど)。 。).
それでも使用しないことのポイントは何ですか? 2つの観点から見てみましょう。
開発者として:@
が使われるとき、どこから始めるべきか全くわかりません。 @
を使って何百、何千もの関数呼び出しがあったとしても、このエラーは毎回のようなものです。この場合、合理的なデバッグは不可能です。たとえそれが単なる3rdpartyエラーであっても - それでそれは丁度良いしあなたは速く終わった。 ;-)さらに、エラーログに十分な詳細を追加することをお勧めします。そのため、開発者は、ログエントリがさらにチェックする必要があるものなのか、それとも開発者の範囲外の単なるサードパーティの障害なのかを簡単に判断できます。
ユーザーとして:ユーザーはエラーの理由がどうであるかどうかはまったく気にしません。彼らはそれが開発者のせいなのかサードパーティの問題なのかどうかを気にしません。特にユーザーにとっては、たとえ範囲外であったとしても、すべてのエラーをログに記録することを強くお勧めします。特定のAPIが頻繁にオフラインになっていることに気付くかもしれません。あなたは何ができますか?あなたはあなたのAPIパートナーと話すことができます、そして、彼らがそれを安定に保つことができないならば、あなたはおそらく他のパートナーを探すべきです。
要するに:@
のようなものが存在することを知っておくべきです(知識は常に良いです)が、そうではありませんそれを使ってください。多くの開発者(特に他の開発者からのコードをデバッグする人)は非常に感謝するでしょう。
"@"演算子を使用していないとすると、コードは次のようになります。
$fileHandle = fopen($fileName, $writeAttributes);
そして、開こうとしているファイルが見つからない場合はどうすればいいですか?エラーメッセージが表示されます。
エラーメッセージを抑制するために、次のように "@"演算子を使用しています。
$fileHandle = @fopen($fileName, $writeAttributes);
オープンに失敗すると、レベルE_WARNINGのエラーが生成されます。この警告を抑制するために@を使用することができます。
@
はエラーメッセージを抑制します。
これは、次のようなコードスニペットで使用されています。
@file_get_contents('http://www.exaple.com');
ドメイン " http://www.exaple.com "にアクセスできない場合、エラーが表示されますが、@
では何も表示されません。
これを追加する価値があるかもしれません@を使用するときに注意する必要があります、この記事を完全に表示するためにここにいくつかのポインタがあります。 /2016/06/30/php速攻phpで使われるシンボルは/
エラーハンドラは、@記号を先頭に追加しても発生します。これは、エラーレベル0が設定されていることを意味します。これは、カスタムエラーハンドラで適切に処理する必要があります。
インクルードの前に@を付けると、インクルードファイル内のすべてのエラーがエラーレベル0に設定されます。
@
は、関数によってスローされたエラーメッセージを抑制します。ファイルが終了しない場合、fopen
はエラーをスローします。 @
シンボルは、ファイルが存在しなくても次の行に移動するように実行します。あなたがPHPコードを開発するとき、私の提案はあなたのローカル環境でこれを使用しないでしょう。