PHPのアットマークの意味について

採用はこちら

PHPのアットマーク @ は、エラー制御演算子と呼ばれる記号です。

関数や変数、配列、式の前に付けることで、その処理中に発生する一部のPHPエラーの報告や表示を抑制できます。

たとえば、次のようなコードです。

$content = @file_get_contents('sample.txt');

この場合、sample.txt が存在しない場合でも、通常表示される warning が画面に出にくくなります。

ただし、@ はエラーを修正するものではありません。

あくまで、エラーを「見えにくくする」ための仕組みです。

そのため、便利そうに見えても、多用するとバグの発見が遅れたり、問題の原因が分かりにくくなったりします。

目次

PHPのアットマーク(@)の基本的な使い方

式の前に付けて使う

@ は、基本的に式の前に付けて使います。

@式

具体的には、次のような書き方をします。

@file_get_contents($path);
@$name;
@$_GET['id'];
@include 'config.php';

たとえば、ファイルを読み込む処理で使う場合は次のようになります。

$data = @file_get_contents('data.txt');

data.txt が存在しない、または読み取り権限がない場合、file_get_contents() は warning を出すことがあります。

しかし、@ を付けることで、その warning の表示を抑制できます。

構文全体には付けられない

@ は「式」に対して使う演算子です。

そのため、次のように if 文そのものに付けることはできません。

@if ($flag) {
    echo 'OK';
}

これは正しい書き方ではありません。

正しくは、エラーが発生する可能性のある式に対して使います。

$result = @file_get_contents($path);

if ($result !== false) {
    echo $result;
}

PHPのアットマーク(@)で抑制できるエラー

warningやnoticeなどを抑制できる

@ は、主に warning、notice、deprecated などのエラー報告を抑制するために使われます。

たとえば、存在しない配列キーにアクセスした場合、PHPのバージョンや設定によっては warning や notice が出ることがあります。

$name = @$_POST['name'];

このように書くと、$_POST['name'] が存在しない場合でも、エラー表示を抑えることができます。

ただし、この書き方は現在ではあまり推奨されません。

後述する ??isset() を使う方が安全で読みやすいです。

PHP 8以降では致命的なエラーは抑制できない

注意したいのは、@ を付ければすべてのエラーを隠せるわけではないという点です。

特にPHP 8以降では、fatal error などの致命的なエラーを @ で抑制することはできません。

たとえば、存在しない関数を呼び出すようなコードです。

@not_existing_function();

このような致命的なエラーは、@ を付けても正常に処理を続けられるわけではありません。

そのため、@ は「どんなエラーでも消せる魔法の記号」ではなく、主に warning や notice などを一時的に抑えるものだと理解しておく必要があります。

例外は抑制できない

@ は例外を握りつぶすためのものではありません。

PHPでは、処理によって TypeErrorValueError などの例外が発生することがあります。

このような例外は、@ では抑制できません。

例外を処理したい場合は、try...catch を使います。

try {
    $result = strlen([]);
} catch (TypeError $e) {
    echo '型が正しくありません。';
}

つまり、@try...catch は役割が異なります。

@ は一部のPHPエラー報告を抑えるもの、try...catch は例外を捕まえて処理するものです。

PHPのアットマーク(@)の具体例

ファイル読み込み時に使う例

@ が使われる代表的な場面のひとつが、ファイルの読み込みです。

$content = @file_get_contents('data.txt');

このコードでは、data.txt が存在しない場合や、読み取り権限がない場合に発生する warning を抑制できます。

ただし、エラーを抑制しただけでは、ファイルが読み込めなかった原因は分かりません。

そのため、戻り値を確認することが重要です。

$content = @file_get_contents('data.txt');

if ($content === false) {
    echo 'ファイルを読み込めませんでした。';
}

file_get_contents() は失敗すると false を返します。

そのため、@ を使う場合でも、失敗時の処理は必ず書くべきです。

ファイルを開くときに使う例

fopen() でも @ が使われることがあります。

$fp = @fopen('data.txt', 'r');

if ($fp === false) {
    echo 'ファイルを開けませんでした。';
}

ファイルが存在しない、権限がない、パスが間違っているといった場合、fopen() は warning を出すことがあります。

@ を付けると、その warning の表示を抑えられます。

ただし、この場合も重要なのは、失敗時の処理を書くことです。

$fp = @fopen($path, 'r');

if ($fp === false) {
    error_log('ファイルを開けませんでした: ' . $path);
}

このように、画面へのエラー表示を抑えつつ、ログには残すという使い方であれば、実務上は意味があります。

ファイル削除時に使う例

ファイルを削除する unlink() でも、@ が使われることがあります。

@unlink('old.txt');

このコードでは、old.txt が存在しない場合や削除権限がない場合に発生する warning を抑制できます。

ただし、何も確認せずに @unlink() だけを書くと、削除に失敗したかどうかが分かりません。

より安全に書くなら、次のようにします。

if (!@unlink('old.txt')) {
    error_log('ファイルを削除できませんでした。');
}

また、事前にファイルの存在を確認する書き方もあります。

if (file_exists('old.txt')) {
    unlink('old.txt');
}

ただし、ファイル操作では、事前に file_exists() で確認しても、その直後に別の処理でファイルが削除される可能性があります。

そのため、最終的には「実行して、失敗したら適切に処理する」という考え方が大切です。

未定義の配列キーに使う例

古いPHPコードでは、次のような書き方を見かけることがあります。

$id = @$_GET['id'];

これは、$_GET['id'] が存在しない場合のエラー表示を抑えるための書き方です。

しかし、現在のPHPではこの書き方はあまりおすすめできません。

代わりに、null合体演算子 ?? を使う方が一般的です。

$id = $_GET['id'] ?? null;

空文字を入れたい場合は、次のように書けます。

$id = $_GET['id'] ?? '';

数値として扱いたい場合は、型変換もあわせて行います。

$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;

このように書くことで、エラーを隠すのではなく、「値が存在しない場合はどうするか」を明示できます。

PHPのアットマーク(@)を使うデメリット

バグに気づきにくくなる

@ を使う最大のデメリットは、バグに気づきにくくなることです。

たとえば、次のコードを見てください。

$total = @$price * $quantity;

このコードでは、もし $price が未定義だったとしても、エラー表示が抑えられてしまいます。

その結果、計算結果がおかしくても、原因に気づきにくくなります。

本来であれば、未定義の変数に気づいてコードを修正すべきです。

しかし @ を付けていると、問題が隠れてしまいます。

エラーの原因が分かりにくくなる

@ は、指定した式の中で発生したエラーを抑制します。

そのため、関数の中で何が起きているのか分かりにくくなることがあります。

$result = @someFunction();

このように書くと、someFunction() の内部で発生した warning も見えにくくなります。

意図したエラーだけを抑えているつもりでも、予想外の問題まで隠してしまう可能性があります。

特に、複雑な関数や外部ライブラリの処理に対して安易に @ を付けるのは避けた方がよいです。

コードの意図が読み取りにくくなる

@ が多いコードは、あとから読む人にとって分かりにくくなります。

@$a = @$_POST['a'];
@$b = @$_POST['b'];
@$content = @file_get_contents(@$url);

このようなコードでは、どのエラーを想定しているのか、なぜ抑制しているのかが分かりません。

コードは、書いた本人だけでなく、将来の自分や他の開発者も読むものです。

そのため、エラーを隠すよりも、条件分岐や戻り値チェックで意図を明確にした方が保守しやすくなります。

パフォーマンス面でも不利になる場合がある

@ はエラー制御のためにPHP内部で追加の処理を行います。

そのため、大量に使うとパフォーマンス面で不利になる可能性があります。

通常のWebサイトで数回使う程度なら大きな問題になることは少ないですが、ループ内で何度も使うような書き方は避けた方がよいです。

foreach ($items as $item) {
    echo @$item['name'];
}

このような場合は、次のように書く方が自然です。

foreach ($items as $item) {
    echo $item['name'] ?? '';
}

PHPのアットマーク(@)を使わない方がよいケース

未定義の変数をごまかすために使う

次のような書き方は避けるべきです。

echo @$title;

$title が未定義であることを隠しているだけだからです。

現在では、次のように書く方が適切です。

echo $title ?? '';

HTMLに出力する場合は、エスケープも行います。

echo htmlspecialchars($title ?? '', ENT_QUOTES, 'UTF-8');

配列キーの存在確認を省略するために使う

次のような書き方も避けた方がよいです。

$name = @$user['name'];

この場合は、?? を使う方が読みやすく安全です。

$name = $user['name'] ?? '';

HTMLに出力するなら、次のようにエスケープします。

echo htmlspecialchars($user['name'] ?? '', ENT_QUOTES, 'UTF-8');

関数の失敗理由を無視するために使う

関数の前に安易に @ を付けるのもおすすめできません。

$result = @someFunction();

この書き方では、関数内で何が失敗したのか分かりにくくなります。

もし失敗する可能性がある処理なら、戻り値を確認する、例外を捕まえる、ログに残すなどの対応を行いましょう。

$result = someFunction();

if ($result === false) {
    error_log('someFunctionの実行に失敗しました。');
}

例外が発生する可能性があるなら、try...catch を使います。

try {
    $result = someFunction();
} catch (Throwable $e) {
    error_log($e->getMessage());
}

PHPのアットマーク(@)の代わりに使いたい書き方

null合体演算子(??)を使う

配列キーや変数が存在するか分からない場合は、@ よりも ?? を使うのがおすすめです。

古い書き方です。

$name = @$_POST['name'];

現在よく使われる書き方です。

$name = $_POST['name'] ?? '';

?? は、左辺が存在しない、または null の場合に右辺の値を返します。

$page = $_GET['page'] ?? 1;

このように書くと、$_GET['page'] が指定されていない場合に 1 を使えます。

isset()を使う

isset() を使って、値が存在するか確認する方法もあります。

if (isset($_POST['name'])) {
    $name = $_POST['name'];
} else {
    $name = '';
}

三項演算子を使うと、次のように短く書けます。

$name = isset($_POST['name']) ? $_POST['name'] : '';

PHP 7以降であれば、多くの場合は ?? の方が簡潔です。

$name = $_POST['name'] ?? '';

empty()を使う

値が空かどうかを確認したい場合は、empty() を使うこともあります。

if (!empty($_POST['name'])) {
    $name = $_POST['name'];
} else {
    $name = '未入力';
}

ただし、empty()0'0' も空として扱います。

そのため、数値や文字列の扱いには注意が必要です。

$value = '0';

if (empty($value)) {
    echo '空です';
}

この場合、'0' も空と判定されます。

フォーム入力などで 0 を有効な値として扱う場合は、isset()?? の方が適していることがあります。

戻り値をチェックする

ファイル操作や外部リソースへのアクセスでは、戻り値のチェックが重要です。

避けたい書き方です。

$content = @file_get_contents($path);

より明示的な書き方です。

$content = file_get_contents($path);

if ($content === false) {
    echo '読み込みに失敗しました。';
}

ただし、file_get_contents() は失敗時に warning を出すことがあります。

そのため、画面にwarningを出したくない場合は、@ を使いつつ戻り値を確認する方法もあります。

$content = @file_get_contents($path);

if ($content === false) {
    error_log('ファイルの読み込みに失敗しました: ' . $path);
}

大切なのは、@ を使うかどうかではなく、失敗時の処理をきちんと書くことです。

try…catchを使う

例外が発生する可能性がある処理では、@ ではなく try...catch を使います。

try {
    // 例外が発生する可能性がある処理
    $result = someFunction();
} catch (Throwable $e) {
    error_log($e->getMessage());
}

Throwable を使うと、ExceptionError の両方を捕まえることができます。

ただし、何でも catch して無視するのはよくありません。

ログを残す、ユーザーに分かりやすいメッセージを表示する、処理を中断するなど、適切な対応を行う必要があります。

WordPressで見かけるアットマーク(@)

古いテーマやプラグインで使われていることがある

WordPressの古いテーマやプラグインでは、次のようなコードを見ることがあります。

$value = @$options['key'];

これは、$options['key'] が存在しない場合の notice や warning を抑えるために使われていることがあります。

しかし、現在のPHPやWordPress開発では、次のように書く方が望ましいです。

$value = $options['key'] ?? '';

出力時はエスケープも重要

WordPressでは、値を画面に出力する際にエスケープ処理を行うことが重要です。

避けたい書き方です。

echo @$post->post_title;

より安全な書き方です。

echo esc_html($post->post_title ?? '');

URLを出力する場合は esc_url() を使います。

echo esc_url($url ?? '');

HTML属性に出力する場合は esc_attr() を使います。

echo esc_attr($value ?? '');

@ でエラーを隠すよりも、値が存在するか確認し、出力先に応じて適切にエスケープすることが大切です。

PHPのアットマーク(@)を使ってもよい場面

失敗する可能性がある処理で、戻り値を確認する場合

@ は基本的に多用すべきではありません。

しかし、実務上まったく使ってはいけないわけではありません。

たとえば、ファイル操作や外部リソースへのアクセスでは、事前に確認していても処理が失敗することがあります。

$fp = @fopen($file, 'r');

if ($fp === false) {
    error_log('ファイルを開けませんでした: ' . $file);
}

このように、エラー表示を抑えつつ、戻り値を確認して適切に処理するのであれば、使いどころはあります。

ユーザーにエラーを直接見せたくない場合

本番環境では、PHPのwarningやnoticeをユーザーにそのまま見せるべきではありません。

そのため、特定の処理で一時的にエラー表示を抑えたい場合に @ を使うことがあります。

ただし、この場合もエラーを完全に無視するのではなく、ログに残すことが重要です。

$result = @file_get_contents($url);

if ($result === false) {
    error_log('外部URLの取得に失敗しました: ' . $url);
}

ユーザーには簡潔なメッセージを表示し、開発者が確認できるようにログを残すのが理想です。

PHPのアットマーク(@)とerror_reportingの違い

@は一部の式にだけ影響する

@ は、付けた式に対してだけ影響します。

$result = @file_get_contents('data.txt');

この場合、file_get_contents('data.txt') の実行中に発生するエラー報告が抑制されます。

つまり、影響範囲はその式だけです。

error_reporting()は全体のエラー報告レベルを変更する

一方、error_reporting() は、PHPスクリプト全体のエラー報告レベルを設定する関数です。

error_reporting(0);

このように書くと、スクリプト全体のエラー報告に影響します。

@error_reporting() の違いをまとめると、次のようになります。

方法影響範囲主な用途
@その式だけ特定の処理のエラー報告を抑える
error_reporting()スクリプト全体エラー報告レベルを設定する
display_errorsPHP設定エラーを画面に表示するか制御する

基本的には、開発環境ではエラーを表示し、本番環境では画面に表示せずログに残す、という運用が望ましいです。

PHPのアットマーク(@)を使うときの注意点

エラーを完全に無視しない

@ を使う場合でも、エラーを完全に無視してはいけません。

悪い例です。

@file_get_contents($path);

このコードでは、読み込みに成功したのか失敗したのか分かりません。

より良い書き方です。

$content = @file_get_contents($path);

if ($content === false) {
    error_log('ファイルを読み込めませんでした: ' . $path);
}

このように、@ を使う場合は、戻り値チェックやログ記録とセットで使うべきです。

多用しない

@ が多いコードは、問題の原因を見つけにくくなります。

@$a = @$_POST['a'];
@$b = @$_POST['b'];
@$c = @$_POST['c'];

このような書き方は避けた方がよいです。

代わりに、次のように書きます。

$a = $_POST['a'] ?? '';
$b = $_POST['b'] ?? '';
$c = $_POST['c'] ?? '';

コードの意図が明確になり、あとから見ても理解しやすくなります。

PHPのバージョン差に注意する

PHPのエラー処理は、バージョンによって挙動が変わることがあります。

特にPHP 8以降では、従来 warning だったものが TypeErrorValueError になるケースがあります。

@ は例外を抑制できないため、PHP 8以降のコードでは、@ に頼ったエラー処理はより危険になっています。

そのため、現在のPHPでは、次のような方針が望ましいです。

やりたいこと推奨される方法
配列キーの存在確認??isset()
変数の存在確認??isset()
ファイルの存在確認file_exists()is_readable()
処理の失敗確認戻り値チェック
例外処理try...catch
エラーの記録error_log()

PHPのアットマーク(@)のまとめ

PHPのアットマーク @ は、エラー制御演算子です。

関数や変数、配列、式の前に付けることで、その式で発生する warning や notice など、一部のPHPエラーの報告や表示を抑制できます。

$content = @file_get_contents('data.txt');

ただし、@ はエラーを修正するものではありません。

エラーの原因を見えにくくしているだけです。

また、PHP 8以降では、fatal error などの致命的なエラーや例外は @ では抑制できません。

例外を処理したい場合は、try...catch を使う必要があります。

基本的には、@ を多用するのではなく、次のような書き方を使うのがおすすめです。

$value = $_GET['id'] ?? '';
if (isset($array['key'])) {
    $value = $array['key'];
}
$content = @file_get_contents($path);

if ($content === false) {
    error_log('ファイルの読み込みに失敗しました。');
}

@ を使う場合は、エラーを隠して終わりにするのではなく、戻り値を確認したり、ログを残したりすることが大切です。

実務では、@ を見かけたら「ここでは何らかのエラーを抑制している」と考えると理解しやすくなります。

自分でコードを書く場合は、@ に頼りすぎず、??isset()try...catch、戻り値チェックなどを使って、エラーを明示的に扱うようにしましょう。

以上、PHPのアットマークの意味についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次