PHPでの@記号の用途は何ですか?


577

@次のような特定の関数の前での使用を見てきました。

$fileHandle = @fopen($fileName, $writeAttributes);

この記号の用途は何ですか?


3
RichieHindleとAiden Bellはどちらも正しい答えを出しましたが、私は1つの答えしか受け入れられないと設定できるので、最初の答えを選択します。申し訳ありませんがAiden
sv_in

1
コードベース...維持するとき(ニースが)道エラーを引き起こす可能性があるエラーを抑制stackoverflow.com/a/7116175/282343
dennismonsewicz

回答:


636

エラーメッセージを抑制します— PHPマニュアルの「エラー制御演算子」を参照してください。


46
それはちょっと早いドローでした!
エイデンベル

6
うん。2番目にダウン!誰が最初に来たのかを確認するために、回答IDを確認する必要がありました:)
サンプソン

3
私が投稿した後、私の抑制のスペルを修正するための時間を持っていた...と同じ時間でリンクを強化するためにあなたのいまいましい激怒:P
エイデンベル

1
クールな機能.. エラーisset()を回避undefined offsetするためにの使用が不要になります。
WM

470

エラーを抑制します。

マニュアルのエラー制御演算子を参照してください:

PHPは、1つのエラー制御演算子、アットマーク(@)をサポートしています。PHPの式の前に付加すると、その式によって生成される可能性のあるエラーメッセージは無視されます。

set_error_handler()でカスタムエラーハンドラー関数を設定した場合でも呼び出されますが、このカスタムエラーハンドラーは、エラーをトリガーした呼び出しの前に@が付いたときに0を返すerror_reporting()を呼び出すことができます(呼び出す必要があります)。 ...


157
他の答えがすべての愛を得ているからといって賛成です。
ajacian81

10
19の後ろに...公民はリッチーヒンドルを倒そう:P
エイデンベル

この答えが最初の答えでした(誰が最初に答えたかに関連して)。
Mohd Abdul Mujib 2018年

227

@シンボルは、エラー制御演算子(別名「沈黙」または「シャットアップ」演算子)。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;
}

58

エラーが非表示になっていても、カスタムエラーハンドラー(で設定set_error_handler)は引き続き実行されます。


34

すでにいくつかが以前に回答したように:@オペレーターは、通知、警告、さらには重大なエラーを含むPHPのすべてのエラーを抑制します。

ただし 、この@演算子はまったく使用しないでください。

どうして?

まあ、@エラー抑制のために演算子を使用すると、エラーが発生したときにどこから始めればよいのかまったくわかりません。私はすでにレガシーコードを「楽しんで」おり、一部の開発@者はかなり頻繁にオペレーターを使用していました。特にファイル操作、ネットワーク呼び出しなどの場合。これらはすべて@、ここでエラーが発生した場合に範囲外となるため、多くの開発者がオペレーターの使用を推奨するケースです(たとえば、サードパーティのAPIに到達できないなど)。 )。

しかし、それをまだ使用しない理由は何ですか?次の2つの視点から見てみましょう。

開発者として:@を使用する場合、どこから始めればよいかまったくわかりません。@エラーが発生した関数呼び出しが数百または数千にも及ぶ場合は、通常のようになります。この場合、合理的なデバッグはできません。そして、それがサードパーティのエラーである場合でも、それは問題なく、すばやく完了します。;-)さらに、エラーログに十分な詳細を追加することをお勧めします。これにより、開発者は、ログエントリがさらに確認する必要がある何かであるか、それともサードパーティの障害であり、開発者の範囲外であるかを簡単に判断できます。

ユーザーとして:ユーザーは、エラーの理由が何であるかをまったく気にしません。ソフトウェアは、動作したり、特定のタスクを完了したりするためのものです。開発者の責任か、サードパーティの問題かは関係ありません。特にユーザーの場合は、範囲外であってもすべてのエラーをログに記録することを強くお勧めします。特定のAPIが頻繁にオフラインになっていることに気付くでしょう。あなたは何ができますか?APIパートナーと話し合うことができ、APIパートナーが安定した状態を維持できない場合は、おそらく別のパートナーを探す必要があります。

要するに:(@知識は常に良い)のようなものが存在することを知っている必要がありますが、それを使用しないでください。多くの開発者(特に他の開発者によるデバッグコード)は非常に感謝します。


1
あなたが整然との方法で、エラー条件を処理するコードを持っている場合、一部の警告が唯一確実に(例えばのfopen()、結果を予測する試みが競合状態にさらされる場所)@用いて抑制することができ、その後、usuigは@正しいことで行いますこれはtext/html、クライアントに戻っていない(または類似していない)場合に特に便利です。(たぶん戻ってくるimage/pngか「json」)
Jasen

1
警告を抑制すべきではありません-彼らはあなたが何か間違ったことをしたと述べています。状態を適切に確認または処理できない競合状態はありません。
Ryan Rentfro 2017

1
いくつかの場所で私のコードに以下があります。if( session_status() == PHP_SESSION_NONE ) session_start(); これは私が継承したレガシーアプリで、セットアップスクリプトが複数回呼び出される場所があるので、テストする必要があります。単に使用することで何か問題はあります@session_start();か?
スティーブンR

あなたが何をしているのかを知っていて、それを控えめに/戦略的に使用するなら、それを使用する価値があります。@$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;各レベルでissetチェックを行い、そうでない場合はそれを埋める方法よりもはるかに優れています。
dtbarne

1
12行以上のコードを追加して値を追加せず、コードの可読性と簡潔さを減らすだけの価値があるのは、どこかで「プレーンダーティー」であるということを読んで、それで私の考えを変えることができるという理由以外にありません。
dtbarne

7

「@」演算子を使用していないとすると、コードは次のようになります。

$fileHandle = fopen($fileName, $writeAttributes);

そして、開こうとしているファイルが見つからない場合はどうなりますか?エラーメッセージが表示されます。

エラーメッセージを抑制するために、次のような「@」演算子を使用しています。

$fileHandle = @fopen($fileName, $writeAttributes);

これは、PHPがこの種の@回避策を最初から用意している理由の完全な例です。他のプログラミング言語は、均一している例外が取り扱うシナリオのこの種に対処するためstackoverflow.com/questions/1087365
dreftymac

@dreftymacまさに!
Sujeet Kumar

5

オープンが失敗した場合、レベルE_WARNINGのエラーが生成されます。@を使用して、この警告を抑制できます。


5

@ エラーメッセージを抑制します。

次のようなコードスニペットで使用されます。

@file_get_contents('http://www.exaple.com');

ドメイン「http://www.exaple.com」にアクセスできない場合、エラーが表示されますが、@何も表示されません。


1

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などの条件付き構造などの前に追加することはできません。

警告:-

現在、 "@"エラー制御演算子のプレフィックスは、スクリプトの実行を終了する重大なエラーのエラー報告を無効にします。とりわけ、これは、「@」を使用して特定の関数からのエラーを抑制し、それが使用できないか、タイプミスされている場合、スクリプトはその理由を示さずにすぐに終了することを意味します。


1

ここに追加する価値があるかもしれませんが、注意が必要な@を使用する際にいくつかのポインタがあります。完全に実行するには、この投稿を参照してください。http//mstd.eu/index.php/2016/06/30/php- php-in-for-in-php /で使用されるRapid-fire-what-is-the-symbol

  1. @記号を前に付けても、エラーハンドラーは引き続き発生します。これは、エラーレベル0が設定されていることを意味します。これは、カスタムエラーハンドラーで適切に処理する必要があります。

  2. インクルードの前に@を付けると、インクルードファイルのすべてのエラーがエラーレベル0に設定されます。


1

@関数によってスローされるエラーメッセージを抑制します。fopenファイルが存在しない場合はエラーをスローします。 @シンボルは、ファイルが存在しなくても次の行に移動するように実行します。私の提案は、PHPコードを開発するときに、ローカル環境でこれを使用しないことです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.