PHP - OOP - 6. 例外(Exception) - 1/2
ここからは例外( Exception
)について学習します。例外( Exception
)とはプログラムの予期せぬ事態を通知する仕組みです。例外とよく似た言葉にエラーがありますが、一般的に、PHPのエラーとは復旧することのできない致命的な問題を意味します。一方の例外は想定外の事態を意味しますが、適切に対処することで処理を継続することも可能となります。
例外の仕組み
PHPには例外を扱うためのクラスとして Exception
クラスが用意されています。 Exception
クラスのインスタンスを生成することで、プログラムの中で例外を生成できます。
$e = new Exception();
また Exception
クラスには例外メッセージを引数にとるコンストラクタも用意されているので、次のように Exception
インスタンスを生成できます。
$e = new Exception("Exctption message.");
生成した例外インスタンスは throw
キーワードによって通知できます。
$e = new Exception("Exctption message.");
throw $e;
PHPでは例外を通知することを「例外をスローする」と言います。スローされた例外インスタンスは後で紹介する try - catch
構文によって処理できるようになっています。
PHPプログラムの開発(0による除算)
それでは簡単な計算機クラス( SimpleCalc.php
)を題材に例外について考えてみましょう。これまでに加算処理を行う add
メソッドを実装しているので、ここでは新たに以下の3つのメソッドを追加して四則演算を完成させます。
- subtractメソッド(減算)
- multiplyメソッド(乗算)
- divideメソッド(除算)
<?php
class SimpleCalc
{
// 省略
public function add($x)
{
$this->number = $this->number + $x;
}
public function subtract($x)
{
$this->number = $this->number - $x;
}
public function multiply($x)
{
$this->number = $this->number * $x;
}
public function divide($x)
{
$this->number = $this->number / $x;
}
public function show()
{
echo $this->number . PHP_EOL;
}
}
ここでは除算を行う divide
メソッドに注目してください。 divide
メソッドの引数に 0
を指定すると 、 0
による除算が発生します。このような演算は行えないため、PHPは実行時に Warning
メッセージを出力します。
実行プログラム( calc_runner.php
)を以下のように修正してみましょう。
<?php
require_once("SimpleCalc.php");
$calc = new SimpleCalc();
$calc->add(10);
$calc->subtract(5);
$calc->multiply(10);
$calc->divide(0); // Warning!
$calc->show();
ここでは $calc->divide(0)
と呼び出している部分で 0
による除算が発生し、戻り値には無限を表す定数 INF
が返却されます。コマンドラインからプログラムを実行してみましょう。
$ php calc_runner.php
Warning: Division by zero in /Users/your_name/Desktop/code-php/SimpleCalc.php on line 40
INF
PHPにおける Warning
メッセージはエラーとは異なります。メッセージは出力されるものの、後続の処理は継続されるようになっています。
PHPプログラムの開発(例外の生成)
次に計算機クラス( SimpleCalc
クラス)の除算を行う divide
メソッドを修正して、 0
による除算が発生した場合は演算を行う前に例外( Exception
インスタンス)をスローするように修正します。
<?php
class SimpleCalc
{
// ...省略
public function divide($x)
{
if ($x == 0) {
$e = new Exception("Divide by 0.");
throw $e;
}
$this->number = $this->number / $x;
}
// ...省略
}
divide
メソッドでは引数 $x
の値が 0
の場合、 Exception
インスタンスを生成して、 throw
キーワードによって例外をスローしています。 throw
キーワードは return
キーワードのように、呼び出されるた時点でメソッドの処理を終了します。
計算機クラス( SimpleCalc.php
)を修正したので、もう一度、実行プログラム( calc_runner.php
)を動かしてみましょう。
$ php calc_runner.php
Fatal error: Uncaught Exception: Divide by 0. in /Users/your_name/Desktop/code-php/SimpleCalc.php:39
Stack trace:
#0 /Users/your_name/Desktop/code-php/calc_runner.php(9): SimpleCalc->divide(0)
#1 {main}
thrown in /Users/your_name/Desktop/code-php/SimpleCalc.php on line 39
実行結果を見ると先ほどのように Warning
メッセージが出力されていないのがわかります。その代わりに Fatal error: Divide by 0.
というメッセージを確認できます。これはPHPの Fatal error
(致命的なエラー)が発生したことを意味しており、その原因として Exception
がキャッチされなかった( Uncaught Exception
)と説明が続きます。またメッセージの後には例外の発生箇所やスタックトレースの出力が確認できます。
ここでは例外をスローする方法として、 Exception
クラスと throw
キーワードについて取り上げました。以降はここでスローされた例外を適切に処理する方法を解説します。
参考:Exceptionクラス
Exception
クラスはPHPに標準で用意されている例外クラスです。 Exception
クラスの詳細については PHPマニュアル - Exceptionを参照してください。
まとめ
- 例外(
Exception
)とはプログラムの予期せぬ事態を通知する仕組み - PHPにはユーザー例外の基底クラスとして
Exception
クラスが用意されている Exception
クラス(および、そのサブクラス)のインスタンスはthrow
キーワードによって、呼び出し元にスローできる