エラー

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