特集
2004/05/25 20:30 更新

UNIX USER 2004年6月号「実践! 最新PHP 5」より転載:
Part 2 Zend Engine 2 (3/3)


final修飾子

 前述したprotected修飾子とprivate修飾子はメンバー変数やメソッドのアクセスに制限を設ける働きがあったが、final修飾子は継承を一切禁止する働きがある。

 継承を許可したくないメソッドに対してfinal宣言を行うことにより、サブクラスでの利用を許可しつつ、メソッドの継承を禁止可能である。リスト13のサンプルスクリプトは、final宣言されているメソッドを継承しているため、実行するとFatal errorとなる(リスト14)。

リスト13 継承を許可したくないメソッドへのfinal宣言
1 <?PHP
2 class Foo
3 {
4 // final宣言しているので、この
5 // メソッドはサブクラスで継承できない
6 final function getToday() {
7 return date("Y-m-d");
8 }
9 }
10
11 class Bar extends Foo
12 {
13 // final宣言したメソッドを継承して
14 // いるので、この部分でエラーになって
15 // しまう
16 function getToday() {
17 return date("Y-m-d",
18 time() - 86400);
19 }
20 }
21
22 $bar = new Bar();
23 ?>

リスト14 final宣言されたメソッドの継承
Fatal error: Cannot override final method Foo::getToday() in /var/www/htdocs/php5/2-2-3.php on line 18

アクセサ

 PHP 5で拡張された機能の中でも面白いのが、このアクセサである。アクセサとは、未定義のメンバー変数やメソッドに対してアクセスがあった場合、あらかじめ用意しておいたメソッドを実行する機能である。

 オブジェクトを利用する側にとっては、そのメンバー変数やメソッドは、あたかも存在しているかのように振る舞う。たとえば、表面上ではメンバー変数として見えるが、実際にはDBの値を参照・更新している、といった芸当も簡単に実現することが可能だ。

 アイデア次第では、アクセサを用いて便利なクラスを作れるので、面白い活用法を考えてみてはいかがだろうか(サンプルスクリプトはリスト15。実行結果はリスト16)。

リスト15 アクセサを用いたクラス作成
1 <?PHP
2 class Foo
3 {
4 // メソッドのアクセサ
5 function __call($method, $args) {
6 // 未定義なメソッドを実行すると、
7 // どのようなメソッドを要求されたのか
8 // を表示する
9 echo "mehtod={$method}\n";
10 var_dump($args);
11 echo "
\n";
12 }
13 }
14
15 $foo = new Foo();
16 $foo->abc("first args");
17 $foo->xyz("second args");
18 ?>

リスト16 アクセサを用いたプログラムの例
mehtod=abc array(1) { [0]=> string(10)
"first args" }
mehtod=xyz array(1) { [0]=> string(11)
"second args" }

例外(try/catch/throw)

 PHP 5では、オブジェクト指向言語の特徴の1つである例外処理もサポートされた。例外とは、処理の中断を要する状況になったことを指し、例外オブジェクトにメッセージを入れて、処理を抜けることを指す。例外が発生する可能性がある範囲をt r yで宣言し、tryの直後に、catchで検出したい例外と例外が発生したときの処理を記述しておく。

 リスト17は、サイコロの裏目を求めるサンプルである。printReverse()メソッドの引数が数字以外であったり、サイコロの目の範囲外であった場合に、例外が発生するようになっている(リスト18)。

リスト17 例外の使用
1 <?PHP
2 // 例外クラス(exceptionクラスを継承
3 // しているだけ)
4 class DiceException extends exception
5 {
6 }
7
8 // サイコロのクラス
9 class Dice
10 {
11 // サイコロの目の裏側の数字を求める
12 public function printReverse($number) {
13 if (!is_int($number)) {
14 // 引数が数値でない場合は例外を
15 // 投げる
16 throw new DiceException
17 ("bad argument value.");
18 } elseif ($number < 0 ||
19 $number > 6) {
20 // 引数がサイコロの目の範囲外なら
21 // 例外を投げる
22 throw new DiceException
23 ("Illegal dice number.");
24 }
25 printf("%d => %d
", $number,
26 7-$number);
27 }
28 }
29
30 $dice = new Dice();
31
32 // 「try{〜}」の範囲で例外が発生したら
33 // 「catch(exception){〜}」で例外を
34 // 検出する
35 try {
36 $dice->printReverse(1);
37 $dice->printReverse(4);
38 $dice->printReverse("a");
39 } catch (DiceException $exception) {
40 // 例外があった場合は、例外メッセージを
41 // 表示する
42 echo $exception->getMessage();
43 }
44 ?>

リスト18 例外の使用(実行結果)
1 => 6
4 => 3
bad argument value.

 リスト17では16行目と22行目にあるthrowで、例外オブジェクトを投げて(throw)いる。35行目で宣言されているtryの範囲内(35〜39行目)で例外が発生した場合、この範囲の処理を抜け、39行目のcatchで例外が検出される。

 もし、catchで宣言されていない例外オブジェクトが発生した場合、Fatal errorとなってしまうので、普段から適切なcatch宣言を行うよう心がけよう。


 PHP 5で拡張された主な機能を駆け足で解説した。ここでは解説しきれなかった機能もあるので、公式サイトもチェックすることをお勧めする。

 Part 3では、PHP 5で新たにバンドルされた機能について、実際にどのようなことができるのかサンプルを交えて解説する。


以降の掲載予定
Part 1 待望のPHP 5リリース
Part 2 Zend Engine 2(本記事)
Part 3 PHP 5に標準バンドルされた機能
Part 4 PHP 4からPHP 5への移行

UNIX USER 6月号表紙 UNIX USER 6月号

第1特集
Linuxで多チャンネル同時録画

第2特集 Windowsメール環境からの脱出
第3特集 実践! 最新PHP 5


前のページ | 1 2 3 |      

[照井進吾,UNIX USER]

Copyright(C) 2010 SOFTBANK Creative Inc. All Right Reserved.