基礎

PHPのエラー制御演算子(@)|エラーメッセージを抑制する方法

PHPのエラー制御演算子 @ は、式の前に付けることで、その式が発生させるエラーメッセージを抑制(非表示に)する演算子です。存在しないファイルの読み込みや、未定義のインデックスへのアクセスなど、エラーが発生する可能性のある処理でエラー表示を抑えたい場合に使われます。

ただし、エラー自体が発生しなくなるわけではなく、あくまで表示を抑制するだけです。根本的なエラー処理の代替にはならないため、使用には十分な注意が必要です。

基本的な使い方

式の前に @ を付けるだけで、その式のエラーメッセージが抑制されます。

PHP
<?php
// @なし:エラーメッセージが表示される
// $result = file_get_contents("存在しないファイル.txt");

// @あり:エラーメッセージが抑制される
$result = @file_get_contents("存在しないファイル.txt");

if ($result === false) {
    echo "ファイルの読み込みに失敗しました\n";
} else {
    echo $result;
}
実行結果
ファイルの読み込みに失敗しました

@ を付けなければ「Warning: file_get_contents(): Failed to open stream...」というエラーメッセージが表示されますが、@ を付けることでこの警告が抑制されます。ただし、関数は false を返すため、戻り値でエラーを検知できます。

使用できる場所

@ は式(expression)の前に付けることができます。変数のアクセス、関数呼び出し、配列要素のアクセスなどが対象です。

PHP
<?php
// 配列の未定義キーへのアクセス
$data = ["name" => "田中"];
$age = @$data["age"];  // Warningを抑制
echo "年齢: " . ($age ?? "不明") . "\n";

// 0除算
$result = @(10 / 0);  // Warningを抑制
echo "結果: " . ($result === false ? "エラー" : $result) . "\n";

// unserializeの失敗
$obj = @unserialize("不正なデータ");
echo "デシリアライズ: " . ($obj === false ? "失敗" : "成功") . "\n";
実行結果
年齢: 不明
結果: INF
デシリアライズ: 失敗

@の代わりに適切なエラー処理を使う

多くの場合、@ よりも適切なエラー処理の方法があります。

PHP
<?php
// 悪い例:@でエラーを握りつぶす
$content = @file_get_contents("config.txt");

// 良い例:事前チェック
$file = "config.txt";
if (file_exists($file) && is_readable($file)) {
    $content = file_get_contents($file);
    echo "読み込み成功: " . strlen($content) . "バイト\n";
} else {
    echo "ファイルが存在しないか読み取れません\n";
}

// 良い例:try-catchを使う(PHP 8.0+ではErrorが発生するケースも)
try {
    $json = json_decode("不正なJSON", true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo "JSONパースエラー: " . $e->getMessage() . "\n";
}
実行結果
ファイルが存在しないか読み取れません
JSONパースエラー: Syntax error

実用的な例

@ の使用が許容されるケースを紹介します。

PHP
<?php
// ソケット接続のタイムアウトチェック
// fsockopenは接続失敗時にWarningを出すため、@で抑制して
// エラー情報は引数で取得するのが一般的
$errno = 0;
$errstr = "";
$fp = @fsockopen("localhost", 9999, $errno, $errstr, 1);

if ($fp === false) {
    echo "接続失敗: [{$errno}] {$errstr}\n";
} else {
    echo "接続成功\n";
    fclose($fp);
}
実行結果
接続失敗: [111] Connection refused
@の危険性

@ はエラーを隠すだけで解決しません。本来修正すべきバグが見過ごされる原因になります。また、PHP 8.0以降では @Fatal Error を抑制することはできなくなりました。デバッグ時に問題の発見が遅れる最大の原因になるため、安易な使用は避けてください。

パフォーマンスへの影響

@ 演算子はPHP内部でエラーレポートレベルを一時的に変更するため、わずかながらパフォーマンスへの影響があります。ループ内で大量に使用する場合は特に注意が必要です。代替手段がある場合は、そちらを優先しましょう。

まとめ

  • @ を式の前に付けると、その式のエラーメッセージが抑制される
  • エラー自体は発生しており、戻り値で検知できる
  • 事前チェックや try-catch の方が適切なエラー処理方法
  • ソケット接続など、代替手段がない場面での使用に限定すべき
  • PHP 8.0以降ではFatal Errorの抑制は不可。デバッグを妨げるため安易に使わない