猫でもわかるWebプログラミング

試行錯誤しながらエンジニア(プログラマー)として働く猫のブログ。技術的な話や、働き方の話、読書録とか、試行錯誤している日常の話。

PHP7の例外(Exception)の関係、正しく例外を使いましょう。

f:id:yoshiki_utakata:20181004212834j:plain

PHP7の例外のうちよく使う例外と構造は以下の通りです。

  • Thorwable
    • Error
    • Exception
      • RuntimeException
      • LogicException

もっと詳細な図は以下の記事を見るとわかりやすいです。

qiita.com

Thorowable

Throwableはすべての例外の基底クラスで、PHP7から新しくできました。

PHP5ではキャッチできなかった例外もここに含まれています。

ただし、Throwable をtry-catchでキャッチしないほうがよいでしょう。構文エラーやロジックのエラーなど、本来コード修正をするべきエラーだからです。Throwable をキャッチするのは、問題を先延ばしにしているようなものです。

Throwable の中には Error と Exception の2種類があります。

Error

PHP5まではキャッチできなかったタイプの例外です。 ParseErrorやTypeErrorなどがErrorに含まれます。

ErrorはPHPの文法エラー等によって起こるものなので、基本的にはキャッチすべきではありません。「コードの書き方が間違っている」時に発生する例外ですので、キャッチするのではなくコードを修正してください。

Exception

PHP5まででもキャッチできた例外です。Exceptionの子クラスには以下のようなクラスがあります。

  • RuntimeException
  • LogicException

大きく分けて「RuntimeException」と「RuntimeException以外」があります、RuntimeException以外でよく使うのはLogicExceptionです。

RuntimeException

RuntimeException は、

  • APIリクエストしようとしたらリクエスト先のサーバーが死んでいた
  • ユーザーからの入力が不正な値だった (UnexpectedValueException)

などのエラーで、必要に応じてキャッチして処理する必要があります。

  • RuntimeExceptionをキャッチして「ただいまシステムエラーが起きています。復旧までしばらくお待ち下さい」という表示を出す。
  • RuntimeExceptionを継承したクラスMaintenanceExceptionを実装し、MaintenanceExceptionをキャッチした場合は「ただいまメンテナンス中です」の表示を出す。
  • PHPに標準で実装されているUnexpectedValueException(RuntimeExceptionを継承している)をキャッチし、「正しいメールアドレスを入力してください」などとユーザーにメッセージを出す。

などという使い方をします。

LogicException

LogicException は、PHPの文法的に間違っているわけではないが、アプリケーションの実装として間違っているので、キャッチせずアプリケーションを修正するべき例外になります。

例えば、

  • Enumに定義されていない値が入っている
  • ユーザーIDが正の整数で渡されることが期待されているのに負の値が来た

などの例外です。この場合は LogicException を継承した InvalidArgumentException を利用するのが良いでしょう。

この例外が発生したらコードを修正する必要があります。

まとめ

  • RuntimeExceptionはキャッチするべき例外。
  • それ以外はキャッチするべきではない例外。コードが間違っているので修正しましょう。
  • キャッチする時だけでなく、スローする時も例外を正しく使いましょう。