Errorクラス
Error は、PHP のすべての内部エラーの基底クラスです。
Throwable(インターフェイス)を実装している。
class Error implements Throwable {...}
ErrorクラスとExceptionクラスはともにThrowableインターフェイスを実装した同階層のクラスです。よって、Exceptionで受け取る以下のようなコードでは、Errorが捕捉されることはありません。
try {
print 1 / 0;
} catch(Exception $e) {
...
}
キャッチし損ねた例外を catch (Exception $e) { … } ブロックで受け止めているような PHP 5 のコードでは、 Error をキャッチできません。
一般的にErrorは実行を継続できない致命的なエラーを意味するので例外を処理する意味はありませんが、もし補足するなら以下のようなコードになります。
try {
print 1 / 0;
} catch(Error $e) {
...
}
set_exception_handler(?callable $callback): ?callable でセットしたユーザー定義の例外ハンドラ関数で補足できる。例外ハンドラがなければ、Fatal errorとなる。
Exceptionクラス
Exception は、 すべてのユーザー例外の基底クラスです。
Throwable(インターフェイス)を実装している。
class Exception implements Throwable {...}
例外クラスで呼び出せるメソッド
メソッド | 概要 |
---|---|
getMessage() | 例外メッセージ |
getCode() | 例外コード |
getFile() | 例外が発生したファイル名 |
getLine() | 例外が発生した行数 |
getTrace() | バックトレース(配列) |
getTraceAsString() | バックトレース(文字列) |
getPrevious() | 前の例外 |
Throwable インターフェイス
Throwable は、throw 文でスロー可能なあらゆるオブジェクトが実装する基底インターフェイスです。 Error や Exception も、これを実装しています。
8.0.0 Throwable は、 Stringable を新たに実装しました。
interface Throwable extends Stringable {
/* メソッド */
public getMessage(): string
public getCode(): int
public getFile(): string
public getLine(): int
public getTrace(): array
public getTraceAsString(): string
public getPrevious(): ?Throwable
abstract public __toString(): string
/* 継承したメソッド */
public Stringable::__toString(): string
}
PHP のクラスが Throwableインターフェイスを直接実装することはできません。 そのかわりに、Exception を継承する必要があります。
スローされるオブジェクトは、Exception クラスあるいは Exception のサブクラスのインスタンスでなければなりません。 それ以外のオブジェクトをスローしようとすると PHP の Fatal Error が発生します。
PHP 8.0.0 以降では、throw キーワードは式として扱えるようになり、 様々なコンテクストで使えるようになりました。 これより前のバージョンでは、throw は文であり、 それが現れる行でだけでしか使えませんでした。
//8.0.0 >= throw式
//条件演算子
$i = -10;
print $i > 0 ? $i : throw new Exception('$iは整数でなければいけません');
//null合体演算子
$str = 'ユーザーネーム';
print $str ?? throw new Exception('変数$strがnullです');
//アロー関数
$hoge = fn() => throw new Exception('エラーです');
//ショートカット演算
$x === 10 || throw new Exception('エラーです');
php 8 以降では例外変数($e)は省略可能
try {....} catch (PDOException $e) {...}
// 8以降↓
try {....} catch (PDOException) {...}
PHP 8.0.0 以降では、キャッチされた例外に対応する変数はオプションになりました。 指定されない場合、catch ブロックは実行されるものの、 投げられたオブジェクトへアクセスすることは出来ません。
例外を握りつぶさない。空のcatchブロックを設置しない。
例外が発生しても通知されず、問題を特定しづらくなる。ログ出力して再スローするなどの方法を考える。
//例外を再スローする例
} catch (Exception $e) {
print $e->getMessage();
throw $e;
}
finally
finally ブロックの中に書いたコードは、 try および catch ブロックの後で常に実行されます。 例外がスローされたかどうかは関係ありません。
return 文が try や catch ブロックの内部に存在した場合でも、 finally ブロックは実行されます。 さらに、return 文は出現した時に評価されますが、 結果は finally ブロックが実行された後に返されます。 さらに、finally ブロックにも return 文が存在した場合は、 finally ブロックから値が返されます = 戻り値が上書きされる。
assert命令
8.0.0 名前空間の内部で、 assert() という名前の関数を宣言することはできなくなりました。 宣言した場合、E_COMPILE_ERROR が発生します。
assert(mixed $assertion, Throwable $exception = ?): bool