例外クラス

 前節で見たように、Exceptionクラスを使うと例外処理をさせることができます。例外処理はそれ以外にも、自分で例外クラスを作って、発生(スロー)させることもできます。

 例外クラスを作成するには次のように記述します。

例外クラス定義の書式
class 例外クラス名 extends Exception
{
 …
}

 例外をスローするには次のように記述します。

例外クラススローの書式
throw 例外オブジェクト;

 ここで、先回作成したBusクラスを修正しましょう。今までは、乗車や降車をするときに走っていないかどうかなどを調べ、異常がある場合はその旨のメッセージを返すように作ってきました。それを例外処理に書き換えましょう。

○ ファイル

 まず、独自の例外クラスを作成しましょう。次の名前のファイルを作成してください。

ファイルの種類 PHPファイル
ファイル名 WarningException.php

サンプルダウンロード

○ プログラム

 次のようにプログラムを入力してください。

WarningException.php

  1. <?php
  2. class WarningException extends Exception
  3. {
  4.  public function __construct($error){
  5.   parent::__construct($error);
  6.  }
  7. }

○ 解説

 2行目でスーパークラスにExceptionクラスを指定しています。それにより今回作成したWarningExceptionクラスはスローしてキャッチすることができるようになります。例外を表すクラスは多くの場合~Exceptionのように名前を付けます。

 4~6行目ではコンストラクタを定義しています。このコンストラクタはインスタンス生成時にスーパークラスであるExceptionクラスのコンストラクタを呼び出しています。引数として受け取ったエラーメッセージをさらに引数として渡しています。これによりgetMessageメソッドで、引数で指定したエラーメッセージが参照できるようになります。

○ ファイル

 次にBusクラスを修正しましょう。

ファイルの種類 PHPファイル
ファイル名 Bus.php

○ プログラム

 次のようにプログラムを修正してください。

Bus.php

  1. //乗車させるメソッド
  2. public function rideToBus($fare){
  3.  //走行中かどうか
  4.  if($this -> getSpeed() != 0){
  5.   throw new WarningException('停車してください。');
  6.  }
  7.  //満席かどうか
  8.  if($this -> passengerNumber >= 50){
  9.   throw new WarningException('満席のため、乗車できません。');
  10.  }
  11.  //料金と、乗車人数を加算する
  12.  $this -> salesAmount += $fare;
  13.  $this -> passengerNumber++;
  14.  return null;
  15. }
  16. //降車させるメソッド
  17. public function getOffBus(){
  18.  if($this -> getSpeed() != 0){
  19.   throw new WarningException('停車してください。');
  20.  }
  21.  //乗客がいるかどうか
  22.  if($this -> passengerNumber == 0){
  23.   throw new WarningException('乗客はいません。');
  24.  }
  25.  //乗車人数を減算
  26.  $this -> passengerNumber--;
  27.  return null;
  28. }

○ 解説

 37、41、53、57行目では、エラーが発生した場合にその時のエラーメッセージをreturn文で返していましたが、throw文を使って例外をスローさせるように変更しました。

○ ファイル

 次にBusクラスを利用するWebページを修正しましょう。「InheritanceTest.php」をコピーして「ThrowTest.php」を作成してください。

ファイルの種類 PHPファイル
ファイル名 ThrowTest.php

○ プログラム

 次のようにプログラムを修正してください。

ThrowTest.php

  1. <?php
  2. //クラスファイルを読み込む
  3. require_once 'Bus.php';
  4. require_once 'WarningException.php';
  5. ?>
  6. <!DOCTYPE html>
  7. <html lang="ja">
  8.  <meta charset="utf-8">
  9.  <head>
  10.   <title>Busオブジェクト実行</title>
  11.  </head>
  12.  <body>
  13. <?php
  14. //バスの状態を表示する関数
  15. function showData($bus){
  16.  print('スピード:' . $bus -> getSpeed() . 'km<br>');
  17.  print('ガソリン:' . $bus -> getGas() . 'L<br>');
  18.  print('売上金額:' . $bus -> getSalesAmount() . '円<br>');
  19.  print('乗車人数:' . $bus -> getPassengerNumber() . '人<br>');
  20. }
  21. try{
  22.  //インスタンスを生成する
  23.  $bus = new Bus(150);
  1.  //降車する
  2.  print('降車します!<br>');
  3.  $ret = $bus -> getOffBus();
  4.  if($ret != null){
  5.   print('<span style="color:red">' . $ret . '</span><br>');
  6.  }
  7.  showData($bus);
  8.  print('<hr>');
  9. }catch(WarningException $e){
  10.  print($e -> getMessage());
  11. }catch(Exception $e){
  12.  print($e -> getMessage());
  13. }
  14. ?>
  15.  </body>
  16. </html>

○ 解説

 22~92行目では、try~catch文が記述されています。このブロック内で、バスオブジェクトのメソッドが呼び出されると、状態によって例外(WarningException)がスローされてきます。その場合は、92行目でキャッチされ、93行目の処理が行われます。94行目はWarningException以外がtry文の中でスローされたときにキャッチされます。

 catch文は複数指定することができます。try文でスローされた例外オブジェクトに応じてキャッチされます。それぞれのcatch文が上から順に評価されていきます。そのため、Exception型のcatchは最後に指定しないとエラーとなります。上の方にExeption型の指定をすると必ずそこでキャッチされ、下に指定したcatch文は使われないからです。

前へ