オブジェクト指向言語に生まれ変わるPHP5[後編]
PHP5の新機能とPHP4との互換性
小山 哲志
2003/5/27
現在開発中のPHP5は、オブジェクト指向機能が大幅に強化される。次世代PHPはどのような言語になるのか? ベータリリースを目前にひかえたPHP5の言語仕様を解説する(編集部)
現在開発中のPHPバージョン5(以下PHP5)。オブジェクト指向機能の大幅な強化が主な改善点であり、巷ではリリースに関する声もちらほら聞かれるようになってきた。
そこで、PHP5の開発経緯やその新機能について、ここでざっとまとめてみたいと思う。
PHP5のリリーススケジュール
前編「ベータリリース目前!? PHP5の新機能」で「Zend社からのニュースレターによれば、間もなくベータリリースされるようだ」と書いたが、開発者内の議論でベータにはまだ時期尚早だという結論になり、近々のベータリリースはされないことになった。
この辺りの動向に興味のある方は、news://news.php.net/でホストされているニュースグループのphp.version5.dev:372で始まるスレッドを参照してほしい。
この件でPHP5のリリースケージュールはまた白紙に戻ったわけだが、その一方でZend Engine 2自体は着実に開発が進んでいる。PHP5のリリースは「早くて年末だろう」というのが現在の大方の予想である。
PHP5の新機能(クラス関係の続き)
それでは早速、前編に引き続いてクラス関係で拡張された機能を見ていこう。
■名前空間
PHP5では、名前空間(namespace)がサポートされた。これにより、クラス、変数、定数、関数を名前空間内に押し込めることができる。
PHP4の変数スコープは、グローバル、関数内、クラス内の3種類しかなかったので、よほど注意してコーディングしないと容易にグローバル空間を汚染してしまっていた。名前空間を使えばパッケージごとに変数空間を分離できるので、より安易に独自パッケージを作成できるようになるだろう。
使用例は以下のとおり。
namespace This { |
名前空間内のリテラルにアクセスするには、
名前空間名::リテラル |
と表記する。ただしPHP5の名前空間は、C++とは異なりネストできない。
■クラス内定数
キーワードconstを用いて、クラス、名前空間内に定数を定義できるようになった。この場合定数なのでリテラルの頭に「$」は必要ない。クラス内定数は、そのクラスの中では同名のグローバル定数より優先される。
これに伴い「const」は予約語となったので、クラス名や関数名にconstを使っている場合は修正が必要となる。
<?php |
この例では、MyClass::printConstant()は定数constant_valueをプリントするが、constant_valueはグローバル空間とクラス内の2カ所に存在する。その場合、MyClass内の定数constant_valueが優先され、「class constant」が表示される。
■クラス変数
クラス変数は、インスタンスを1つも作らない状態でも、きちんと指定した値で初期化されるようになった。アクセス方法は、
クラス名::$変数名 |
となる。
<?php |
■統一コンストラクタ
オブジェクトが生成される際、自動的に呼ばれるメソッドを「コンストラクタ」という。
PHP4のコンストラクタは、クラス名と同名のメソッドだった。これはJavaやC++と同じ仕様なので、そちらに慣れている人には違和感がないのだが、子クラスから親クラスのコンストラクタを呼びたい場合、Javaでいうsuper()が存在しないPHPでは親クラスの名前をわざわざ書かなければならない。PHPでは親クラスのコンストラクタは自動的に呼ばれないので、そうしたケースは比較的多い。
そこでPHP5では、__construct(注)という統一コンストラクタ名を採用した。クラス名にかかわらず、__construct()というメソッドがコンストラクタとして扱われる。
【注】 __constructの「__」は、「_」が2つ連続している。以下に登場する「__」も同様。 |
またPHP4との互換性のため、クラス名と同名の従来のコンストラクタが存在すれば、そちらが優先して使用される。
<?php |
■デストラクタ
コンストラクタとは逆に、オブジェクトが消滅するときに自動的に呼ばれるメソッドを「デストラクタ」という。
PHP4ではデストラクタはサポートされておらず、register_shutdown_function()でPHPの実行終了時に呼び出される関数を登録することにより、疑似的に実現するしか方法がなかった。PHP5では正式にデストラクタがサポートされ、クラスごとにオブジェクトの消滅時の振る舞いを指定できるようになった。
デストラクタは、__destructという名前のメソッドになる。オブジェクトの内部的な参照カウンタが0になると、__destruct()メソッドが呼び出され、その後でオブジェクトが保持しているメモリ領域が解放される。
<?php |
なお、コンストラクタがそうであるのと同様に、親クラスのデストラクタが自動的に呼び出されることはない。必要な場合は、
parent::__destruct(); |
と記述して、明示的に呼び出してやる必要がある。
■アクセサ
PHP4では、存在しないプロパティへアクセスが発生すると、自動的にそのプロパティを生成することで対応していた。例えば、
class Hoge { |
のように、存在しないプロパティに値を代入しようとすると、代入時点でそのプロパティが生成される。同様に、存在しないプロパティの参照も、(Warning付きではあるが)null値が代入された変数があるかのように振る舞い、決してエラーになることはない。
PHP5ではこれに追加して、任意のプロパティへのアクセスを制御できる仕組みが導入された。クラスに__set()、__get()というメソッドが存在すると、上記の振る舞いの代わりにこれらのメソッドが呼び出される。例を見てみよう。
<?php |
ここでは、__setメソッドは引数をプリントした後にそのままプロパティとして代入している。
$obj->a = '123'; |
で$obj->aに値を代入しているが、この時点ではプロパティaは存在しないので、代わりに__setメソッドが呼び出される。
__set() is called with (a, 123) |
と表示されるはずだ。次に、
$obj->a = '456'; |
ともう一度$obj->aに代入している。今度は先ほどの代入でプロパティaが存在するので__setメソッドは呼び出されず、通常のプロパティ代入となる。
さらに今度は、
$obj->b = '789'; |
として別のプロパティbに代入すると、aの1回目と同様に、
__set() is called with (b, 789) |
と表示されるだろう。
__getメソッドは、__setとは逆で、存在しないプロパティへの参照を上書きする。__setと__getを組み合わせると、プロパティへのアクセスのように見えて、実は全然違う場所に影響を与えるクラスを作成することができる。
<?php |
この例では、クラスHogeのすべてのプロパティアクセスを$propertiesという配列に押し込めている。これはオブジェクト直下のプロパティをあまり使わないだけで、何がうれしいのかよく分からない例だが、この保存先を例えばファイルやDBに変えてみたりするのも面白いだろう。一見オブジェクトに何げなくアクセスしているように見えて、実は裏ではたくさんのコードが動いているということが簡単に実現できる。
__set、__getとは多少趣が違うが、__callという、存在しないメソッドを上書きするものも用意されている。オブジェクトのメソッドを以下のように呼んだとき、
$object->methodname(); |
もしそのクラスにmethodnameというメソッドが存在しなければ、通常ならば、
Fatal error: Call to undefined method Class::methodname() |
というエラーになる。だが、__callというメソッドがそのクラスにある場合、代わりに__callが呼び出される。__callの引数は2つで、第1引数は呼び出されたメソッド名、第2引数は呼び出し時の引数を保持した配列だ。使い方はいろいろ考えられるが、例えば以下のようにほかのオブジェクトへ呼び出しを委譲するといったことができる。
<?php |
1/2 |
Index | |
PHP5の新機能とPHP4との互換性 | |
Page1 PHP5のリリーススケジュール PHP5の新機能(クラス関係の続き) 名前空間 クラス内定数 クラス変数 統一コンストラクタ デストラクタ アクセサ |
|
Page2 クラス以外の拡張機能 引数が参照の場合のデフォルト値 __autoload() 例外処理 そのほか PHP4との互換性 まとめ |
オブジェクト指向言語に生まれ変わるPHP5 |
PHP関連記事 |
例外処理の実装を把握する PHP5で広がる! 開発環境(1) PHP4のサポートが終了し、いよいよPHP5への移行を視野に入れる時期が来た。PHP5の機能を生かした開発のポイントを紹介 |
|
クライアントPCに言語環境を入れる理由 Mac OS X+PHPでオールインワン環境(準備編) Webアプリ開発者に人気のMac OS X。効率的な開発のために複数バージョンのPHPを実行する環境を構築してみよう |
|
PHPに押し寄せるリスクと国際化の波 PHPカンファレンス2008レポート(前編) PHP4のサポートが完全に終了する。多くの新機能が投入されるPHP5.3へ移行か、国際化対応で開発が遅れるPHP6を待つか |
|
PHPによる大規模商用サービスの裏側 PHPカンファレンス2008レポート(中編) 企業のWebアプリケーション開発現場で利用されるPHP。開発現場の裏側にはさまざまなドラマが隠されている |
|
PHPユーザーは本当にほかの言語を知らないのか? PHPカンファレンス2008レポート(後編) PHPは本当にダメな言語なのだろうか。Perl、Ruby、Python、Java、JavaScriptの使い手が白熱した議論を行った |
|
- プログラムの実行はどのようにして行われるのか、Linuxカーネルのコードから探る (2017/7/20)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。最終回は、Linuxカーネルの中では、プログラムの起動時にはどのような処理が行われているのかを探る - エンジニアならC言語プログラムの終わりに呼び出されるexit()の中身分かってますよね? (2017/7/13)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。今回は、プログラムの終わりに呼び出されるexit()の中身を探る - VBAにおけるFileDialog操作の基本&ドライブの空き容量、ファイルのサイズやタイムスタンプの取得方法 (2017/7/10)
指定したドライブの空き容量、ファイルのタイムスタンプや属性を取得する方法、FileDialog/エクスプローラー操作の基本を紹介します - さらば残業! 面倒くさいエクセル業務を楽にする「Excel VBA」とは (2017/7/6)
日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。本稿では、業務で使うことが多い「Microsoft Excel」で使えるVBAを紹介する。※ショートカットキー、アクセスキーの解説あり
|
|