PHPで例外(Exception)を使ったエラーハンドリングはもはや標準的な手法ですが、それ以前から存在する「ユーザー定義エラー」という仕組みをご存知でしょうか。trigger_error() を使うと、PHP組み込みのエラーシステムに乗せる形で、独自のエラーメッセージや警告を発生させることができます。
ライブラリの非推奨警告、設定ミスの通知、ログとの連携など、例外とは違った使い道があります。この記事では trigger_error() の基本仕様から実践的な活用パターン、例外との使い分けまで詳しく解説します。
関数概要
| 項目 | 内容 |
|---|---|
| 関数名 | trigger_error()(エイリアス:user_error()) |
| 読み方 | トリガーエラー |
| 分類 | エラー処理関数 |
| 対応バージョン | PHP 4以降(全バージョンで使用可能) |
| 引数 | エラーメッセージ(必須)、エラーレベル(省略可) |
| 戻り値 | bool(true) |
| 名前空間 | グローバル関数 |
| 関連拡張モジュール | 標準で組み込み(拡張モジュール不要) |
構文
trigger_error(string $message, int $error_level = E_USER_NOTICE): bool
第1引数にはエラーメッセージの文字列を、第2引数には発生させるエラーのレベル(重要度)を指定します。第2引数は以下の3種類のいずれかを指定できます(PHPの組み込みエラーレベルのうち、ユーザーが意図的に発生させられるものに限定されています)。
| 定数 | 重要度 | 意味 |
|---|---|---|
E_USER_NOTICE | 低(デフォルト) | 軽微な通知。処理は継続される |
E_USER_WARNING | 中 | 警告。処理は継続されるが注意が必要 |
E_USER_ERROR | 高 | 致命的エラー。スクリプトの実行が停止する |
E_USER_DEPRECATED | 低 | 非推奨の使用方法であることの通知(PHP 5.3以降) |
基本的な使い方
<?php
function divide(int $a, int $b): float
{
if ($b === 0) {
trigger_error('ゼロで除算しようとしました', E_USER_WARNING);
return 0.0;
}
return $a / $b;
}
$result = divide(10, 0);
echo "結果: {$result}" . PHP_EOL;
実行結果:
Warning: ゼロで除算しようとしました in /path/to/script.php on line 6
結果: 0
trigger_error() を呼んでも、E_USER_WARNING や E_USER_NOTICE の場合はプログラムの実行が継続される点が、後述する E_USER_ERROR との大きな違いです。
処理の流れ
trigger_error("メッセージ", レベル)
│
▼
PHPの標準エラーハンドラ
(または set_error_handler() で
登録した独自のハンドラ)
│
├─→ E_USER_NOTICE / E_USER_WARNING / E_USER_DEPRECATED
│ → エラーメッセージを出力(またはログに記録)
│ → 処理はそのまま継続される
│
└─→ E_USER_ERROR
→ エラーメッセージを出力
→ スクリプトの実行がそこで停止する
実践的なコード例
例1:非推奨になった関数の使用を警告する
<?php
class LegacyApiClient
{
public function fetchDataOldWay(string $url): string
{
trigger_error(
'fetchDataOldWay()は非推奨です。fetchData()を使用してください。',
E_USER_DEPRECATED
);
return $this->fetchData($url);
}
public function fetchData(string $url): string
{
return "データ取得: {$url}";
}
}
$client = new LegacyApiClient();
echo $client->fetchDataOldWay('https://api.example.com') . PHP_EOL;
実行結果:
Deprecated: fetchDataOldWay()は非推奨です。fetchData()を使用してください。 in /path/to/script.php on line 6
データ取得: https://api.example.com
ライブラリやフレームワークの開発で、古いメソッドを段階的に廃止していく際の通知として E_USER_DEPRECATED がよく使われます。
例2:設定値の異常を警告として記録する
<?php
class ConfigValidator
{
public function validate(array $config): array
{
$defaults = ['timeout' => 30, 'retry' => 3];
foreach ($defaults as $key => $defaultValue) {
if (!isset($config[$key])) {
trigger_error(
"設定キー '{$key}' が見つからないため、デフォルト値 {$defaultValue} を使用します。",
E_USER_NOTICE
);
$config[$key] = $defaultValue;
}
}
return $config;
}
}
$validator = new ConfigValidator();
$config = $validator->validate(['timeout' => 60]);
print_r($config);
実行結果:
Notice: 設定キー 'retry' が見つからないため、デフォルト値 3 を使用します。 in /path/to/script.php on line 10
Array
(
[timeout] => 60
[retry] => 3
)
致命的ではないが「気づいてほしい」設定の問題を通知する際に E_USER_NOTICE が適しています。
例3:set_error_handler()と組み合わせてログに記録する
<?php
class ErrorLogger
{
private array $logs = [];
public function register(): void
{
set_error_handler([$this, 'handle']);
}
public function handle(int $errno, string $errstr): bool
{
$levelNames = [
E_USER_NOTICE => 'NOTICE',
E_USER_WARNING => 'WARNING',
E_USER_ERROR => 'ERROR',
E_USER_DEPRECATED => 'DEPRECATED',
];
$levelName = $levelNames[$errno] ?? 'UNKNOWN';
$this->logs[] = "[{$levelName}] {$errstr}";
// trueを返すとPHPの標準エラーハンドラの処理をスキップする
return true;
}
public function getLogs(): array
{
return $this->logs;
}
}
$logger = new ErrorLogger();
$logger->register();
trigger_error('在庫が残りわずかです', E_USER_NOTICE);
trigger_error('APIのレスポンスが遅延しています', E_USER_WARNING);
restore_error_handler();
print_r($logger->getLogs());
実行結果:
Array
(
[0] => [NOTICE] 在庫が残りわずかです
[1] => [WARNING] APIのレスポンスが遅延しています
]
set_error_handler() と組み合わせることで、trigger_error() で発生させたメッセージを画面出力ではなく独自のログファイルや監視システムに送る、といった柔軟な制御が可能になります。
例4:致命的エラーで処理を強制停止させる
<?php
class CriticalResourceChecker
{
public function checkDiskSpace(int $freeSpaceMb): void
{
if ($freeSpaceMb < 100) {
trigger_error(
"ディスク空き容量が危険なレベルです(残り{$freeSpaceMb}MB)。処理を中止します。",
E_USER_ERROR
);
}
echo "ディスク容量チェックOK。処理を続行します。" . PHP_EOL;
}
}
$checker = new CriticalResourceChecker();
$checker->checkDiskSpace(50);
echo "この行は実行されません。" . PHP_EOL;
実行結果:
Fatal error: ディスク空き容量が危険なレベルです(残り50MB)。処理を中止します。 in /path/to/script.php on line 7
E_USER_ERROR を指定すると、その時点でスクリプトの実行が完全に停止します。これより後ろのコード(echo "この行は実行されません。"を含む)は一切実行されません。
注意:PHP 8.0以降では多くの内部エラーが
Error/TypeErrorなどの例外として扱われるようになりました。新規開発で「処理を止めたい」場合は、trigger_error(..., E_USER_ERROR)よりもthrow new RuntimeException(...)のように例外をスローするほうが、try-catchでの柔軟な制御ができるため一般的に推奨されます。
例5:APIのバリデーションエラーを警告として収集する
<?php
class ApiRequestValidator
{
public function validate(array $data): bool
{
$isValid = true;
if (empty($data['email'])) {
trigger_error('emailパラメータが指定されていません。', E_USER_WARNING);
$isValid = false;
}
if (isset($data['age']) && $data['age'] < 0) {
trigger_error('ageパラメータには0以上の値を指定してください。', E_USER_WARNING);
$isValid = false;
}
return $isValid;
}
}
$validator = new ApiRequestValidator();
$result = $validator->validate(['age' => -5]);
var_dump($result);
実行結果:
Warning: emailパラメータが指定されていません。 in /path/to/script.php on line 7
Warning: ageパラメータには0以上の値を指定してください。 in /path/to/script.php on line 11
bool(false)
複数のバリデーションエラーをすべて警告として出しつつ、戻り値で全体の成否も返す、というハイブリッドな設計です。
例6:error_reporting()のレベルによる出力制御を確認する
<?php
class NoticeEmitter
{
public function emit(): void
{
trigger_error('これはNOTICEレベルのメッセージです。', E_USER_NOTICE);
}
}
$emitter = new NoticeEmitter();
echo "--- E_ALL の場合 ---" . PHP_EOL;
error_reporting(E_ALL);
$emitter->emit();
echo "--- E_ALL & ~E_NOTICE & ~E_USER_NOTICE の場合 ---" . PHP_EOL;
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE);
$emitter->emit();
echo "(NOTICEレベルが抑制されているため、上記のメッセージは表示されません)" . PHP_EOL;
実行結果:
--- E_ALL の場合 ---
Notice: これはNOTICEレベルのメッセージです。 in /path/to/script.php on line 6
--- E_ALL & ~E_NOTICE & ~E_USER_NOTICE の場合 ---
(NOTICEレベルが抑制されているため、上記のメッセージは表示されません)
trigger_error() で発生させたメッセージが実際に画面に表示されるかどうかは、error_reporting() の設定や display_errors の設定に依存します。本番環境では通常、画面表示は無効化されログにのみ記録される設定が推奨されます。
例7:デバッグ情報を含めたコンテキスト付きエラー
<?php
class DataProcessor
{
public function process(array $items): array
{
$results = [];
foreach ($items as $index => $item) {
if (!is_numeric($item)) {
trigger_error(
sprintf(
'配列のインデックス%dに数値以外の値「%s」が含まれています。スキップします。',
$index,
var_export($item, true)
),
E_USER_WARNING
);
continue;
}
$results[] = $item * 2;
}
return $results;
}
}
$processor = new DataProcessor();
$result = $processor->process([1, 2, 'abc', 4, null]);
print_r($result);
実行結果:
Warning: 配列のインデックス2に数値以外の値「'abc'」が含まれています。スキップします。 in /path/to/script.php on line 12
Warning: 配列のインデックス4に数値以外の値「NULL」が含まれています。スキップします。 in /path/to/script.php on line 12
Array
(
[0] => 2
[1] => 4
[2] => 8
)
エラーメッセージに発生箇所のコンテキスト(インデックス番号や該当データの中身)を含めておくと、後からログを見返した際の原因特定がしやすくなります。
関連関数との比較
| 関数/構文 | 役割 | 処理継続の可否 |
|---|---|---|
trigger_error() | ユーザー定義のエラー・警告を発生させる | レベルによる(NOTICE/WARNINGは継続、ERRORは停止) |
throw new Exception() | 例外をスローする | try-catchで捕捉されなければ停止 |
set_error_handler() | エラー発生時の処理をカスタマイズする | ハンドラの実装次第 |
error_log() | メッセージをログファイルやシステムログに記録する | 常に継続(出力に影響しない) |
assert() | 開発時の前提条件チェック | 設定により例外化・警告いずれも可能 |
die() / exit() | 即座にスクリプトを終了する | 常に停止 |
trigger_error() の大きな特徴は、PHPの標準エラーシステムに統合されるという点です。error_log() のように直接ログに書き込むわけではなく、set_error_handler() で登録したハンドラを経由させたり、error_reporting() の設定でレベルごとに出力を制御したりできる柔軟性があります。一方、現代的なPHP開発では、回復可能なエラー処理には例外(throw)を使い、trigger_error() は「警告・非推奨通知」のような軽量な用途に限定するという使い分けが一般的です。
よくある落とし穴・注意点
E_USER_ERRORはtry-catchで捕捉できない 一見「エラーを発生させる」という名前から例外のように扱えそうに思えますが、E_USER_ERRORは従来型のPHPエラーであり、try-catchで捕捉することはできません(PHP 7以降であれば、set_error_handler()で例外に変換することは可能です)。確実に捕捉可能なエラーハンドリングが必要な場合は、throw new Exception()を使うべきです。- 本番環境でメッセージが画面に表示されてしまうリスク
display_errorsが有効な本番環境でtrigger_error()を多用すると、内部のロジックやファイルパスなどの情報がユーザーに見えてしまう可能性があります。本番環境ではdisplay_errorsをOffにし、log_errorsをOnにしてログにのみ記録する構成が推奨されます。 - 戻り値は常に
trueであり、エラーの成否を表すものではないtrigger_error()の戻り値は常にtrue(エラーが正しく発生した場合)であり、処理の成否を判定するためのものではありません。if (trigger_error(...))のような使い方は意味を持たないため注意してください。 - 第2引数に指定できるレベルは4種類のみ
E_WARNINGやE_NOTICEのような「PHP内部が発生させるレベル」をtrigger_error()の第2引数に直接指定することはできません。指定可能なのはE_USER_NOTICE、E_USER_WARNING、E_USER_ERROR、E_USER_DEPRECATEDの4つ(ユーザー定義用に用意されたもの)のみです。 - PHP 8系での例外中心の設計トレンドとの兼ね合い PHP 7以降、多くの内部的なエラーが
Errorクラス(TypeError、ValueErrorなど)の例外として再設計されました。新規プロジェクトでは、回復可能なエラーロジックの多くを例外ベースで設計するのが主流になりつつあり、trigger_error()は「ライブラリの非推奨化通知」など限定的な用途で使われることが多くなっています。プロジェクトの設計方針に応じて、例外と使い分けることが重要です。
まとめ
| ポイント | 内容 |
|---|---|
| 役割 | ユーザー定義のエラー・警告・通知を発生させる |
| 引数 | 第1引数:メッセージ(必須)、第2引数:エラーレベル(省略可) |
| 戻り値 | bool(常にtrue) |
| 指定可能なレベル | E_USER_NOTICE, E_USER_WARNING, E_USER_ERROR, E_USER_DEPRECATED |
| 処理継続 | NOTICE/WARNING/DEPRECATEDは継続、ERRORは停止 |
| よく組み合わせる関数 | set_error_handler(), error_reporting() |
| 主な用途 | 非推奨警告、設定値の異常通知、軽量なバリデーション警告 |
| 注意点 | try-catchで捕捉不可、本番環境での情報漏えいリスク |
trigger_error() は例外ほど厳格な制御は持たないものの、PHPの標準エラーシステムに統合された軽量な通知手段として、特に「非推奨警告」や「致命的ではないが気づいてほしい問題」を伝える場面で今でも活躍しています。例外との役割の違いを理解し、プロジェクトの設計方針に合わせて適切に使い分けましょう。
