@
次のような特定の関数の前での使用を見てきました。
$fileHandle = @fopen($fileName, $writeAttributes);
この記号の用途は何ですか?
@
次のような特定の関数の前での使用を見てきました。
$fileHandle = @fopen($fileName, $writeAttributes);
この記号の用途は何ですか?
回答:
エラーを抑制します。
マニュアルのエラー制御演算子を参照してください:
PHPは、1つのエラー制御演算子、アットマーク(@)をサポートしています。PHPの式の前に付加すると、その式によって生成される可能性のあるエラーメッセージは無視されます。
set_error_handler()でカスタムエラーハンドラー関数を設定した場合でも呼び出されますが、このカスタムエラーハンドラーは、エラーをトリガーした呼び出しの前に@が付いたときに0を返すerror_reporting()を呼び出すことができます(呼び出す必要があります)。 ...
@
シンボルは、エラー制御演算子(別名「沈黙」または「シャットアップ」演算子)。PHPは、関連付けられた式によって生成されたエラーメッセージ(通知、警告、致命的など)を抑制します。これは、単項演算子のように機能します。たとえば、優先順位と結合性があります。以下にいくつかの例を示します。
@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()でカスタムエラーハンドラー関数を設定した場合でも呼び出されますが、このカスタムエラーハンドラーは、エラーをトリガーした呼び出しの前に@が付いたときに0を返す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;
}
すでにいくつかが以前に回答したように:@
オペレーターは、通知、警告、さらには重大なエラーを含むPHPのすべてのエラーを抑制します。
ただし 、この@
演算子はまったく使用しないでください。
どうして?
まあ、@
エラー抑制のために演算子を使用すると、エラーが発生したときにどこから始めればよいのかまったくわかりません。私はすでにレガシーコードを「楽しんで」おり、一部の開発@
者はかなり頻繁にオペレーターを使用していました。特にファイル操作、ネットワーク呼び出しなどの場合。これらはすべて@
、ここでエラーが発生した場合に範囲外となるため、多くの開発者がオペレーターの使用を推奨するケースです(たとえば、サードパーティのAPIに到達できないなど)。 )。
しかし、それをまだ使用しない理由は何ですか?次の2つの視点から見てみましょう。
開発者として:@
を使用する場合、どこから始めればよいかまったくわかりません。@
エラーが発生した関数呼び出しが数百または数千にも及ぶ場合は、通常のようになります。この場合、合理的なデバッグはできません。そして、それがサードパーティのエラーである場合でも、それは問題なく、すばやく完了します。;-)さらに、エラーログに十分な詳細を追加することをお勧めします。これにより、開発者は、ログエントリがさらに確認する必要がある何かであるか、それともサードパーティの障害であり、開発者の範囲外であるかを簡単に判断できます。
ユーザーとして:ユーザーは、エラーの理由が何であるかをまったく気にしません。ソフトウェアは、動作したり、特定のタスクを完了したりするためのものです。開発者の責任か、サードパーティの問題かは関係ありません。特にユーザーの場合は、範囲外であってもすべてのエラーをログに記録することを強くお勧めします。特定のAPIが頻繁にオフラインになっていることに気付くでしょう。あなたは何ができますか?APIパートナーと話し合うことができ、APIパートナーが安定した状態を維持できない場合は、おそらく別のパートナーを探す必要があります。
要するに:(@
知識は常に良い)のようなものが存在することを知っている必要がありますが、それを使用しないでください。多くの開発者(特に他の開発者によるデバッグコード)は非常に感謝します。
@
正しいことで行いますこれはtext/html
、クライアントに戻っていない(または類似していない)場合に特に便利です。(たぶん戻ってくるimage/png
か「json」)
if( session_status() == PHP_SESSION_NONE ) session_start();
これは私が継承したレガシーアプリで、セットアップスクリプトが複数回呼び出される場所があるので、テストする必要があります。単に使用することで何か問題はあります@session_start();
か?
@$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;
各レベルでissetチェックを行い、そうでない場合はそれを埋める方法よりもはるかに優れています。
「@」演算子を使用していないとすると、コードは次のようになります。
$fileHandle = fopen($fileName, $writeAttributes);
そして、開こうとしているファイルが見つからない場合はどうなりますか?エラーメッセージが表示されます。
エラーメッセージを抑制するために、次のような「@」演算子を使用しています。
$fileHandle = @fopen($fileName, $writeAttributes);
@
回避策を最初から用意している理由の完全な例です。他のプログラミング言語は、均一している例外が取り扱うシナリオのこの種に対処するためstackoverflow.com/questions/1087365
@
エラーメッセージを抑制します。
次のようなコードスニペットで使用されます。
@file_get_contents('http://www.exaple.com');
ドメイン「http://www.exaple.com」にアクセスできない場合、エラーが表示されますが、@
何も表示されません。
PHPは1つのエラー制御演算子、アットマークをサポートしています(@)
。PHPの式の前に付加すると、その式によって生成される可能性のあるエラーメッセージは無視されます。
あなたがカスタムエラーハンドラ関数を設定している場合set_error_handler()
、それはまだ呼ばれますが、このカスタムエラーハンドラ缶(とすべきである)の呼び出しerror_reporting()
が返されます0
エラーを引き起こしたコールが先行されたとき@
。
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
注意:-
1)@演算子は式でのみ機能します。
2)簡単な経験則は次のとおりです。何かの値を取得できる場合は、それに@演算子を付加できます。たとえば、変数や関数の前に追加して、呼び出しや定数などを含めることができます。関数やクラスの定義、ifやforeachなどの条件付き構造などの前に追加することはできません。
警告:-
現在、 "@"エラー制御演算子のプレフィックスは、スクリプトの実行を終了する重大なエラーのエラー報告を無効にします。とりわけ、これは、「@」を使用して特定の関数からのエラーを抑制し、それが使用できないか、タイプミスされている場合、スクリプトはその理由を示さずにすぐに終了することを意味します。
ここに追加する価値があるかもしれませんが、注意が必要な@を使用する際にいくつかのポインタがあります。完全に実行するには、この投稿を参照してください。http://mstd.eu/index.php/2016/06/30/php- php-in-for-in-php /で使用されるRapid-fire-what-is-the-symbol
@記号を前に付けても、エラーハンドラーは引き続き発生します。これは、エラーレベル0が設定されていることを意味します。これは、カスタムエラーハンドラーで適切に処理する必要があります。
インクルードの前に@を付けると、インクルードファイルのすべてのエラーがエラーレベル0に設定されます。
@
関数によってスローされるエラーメッセージを抑制します。fopen
ファイルが存在しない場合はエラーをスローします。 @
シンボルは、ファイルが存在しなくても次の行に移動するように実行します。私の提案は、PHPコードを開発するときに、ローカル環境でこれを使用しないことです。