哲志2003/5/27現在開発中のPHP5は、オブジェクト指向機能が大幅に強化される。-現在開発中のPHPバージョン5(以下PHP5)。オブジェクト指向機能の大幅な強化が主な改善点であり、巷ではリリースに関する声もちらほら聞かれるようになってきた。そこで、PHP5の開発経緯やその新機能について、ここでざっとまとめてみたいと思う。PHP5の新機能」で「Zend社からのニュースレターによれば、間もなくベータリリースされるようだ」と書いたが、開発者内の議論でベータにはまだ時期尚早だという結論になり、近々のベータリリースはされないことになった。この辺りの動向に興味のある方は、news://news.php.net/でホストされているニュースグループのphp.version5.dev:372で始まるスレッドを参照してほしい。2自体は着実に開発が進んでいる。PHP5のリリースは「早くて年末だろう」というのが現在の大方の予想である。PHP5の新機能(クラス関係の続き)それでは早速、前編に引き続いてクラス関係で拡張された機能を見ていこう。■名前空間PHP5では、名前空間(namespace)がサポートされた。名前空間内に押し込めることができる。PHP4の変数スコープは、グローバル、関数内、クラス内の3種類しかなかったので、よほど注意してコーディングしないと容易にグローバル空間を汚染してしまっていた。名前空間を使えばパッケージごとに変数空間を分離できるので、より安易に独自パッケージを作成できるようになるだろう。使用例は以下のとおり。名前空間名::リテラルと表記する。PHP5の名前空間は、C++とは異なりネストできない。■クラス内定数キーワードconstを用いて、クラス、名前空間内に定数を定義できるようになった。この場合定数なのでリテラルの頭に「$」は必要ない。クラス内定数は、そのクラスの中では同名のグローバル定数より優先される。これに伴い「const」は予約語となったので、クラス名や関数名にconstを使っている場合は修正が必要となる。"<br>\n";MyClass::printConstant();?>この例では、MyClass::printConstant()は定数constant_valueをプリントするが、constant_valueはグローバル空間とクラス内の2カ所に存在する。constant」が表示される。■クラス変数クラス変数は、インスタンスを1つも作らない状態でも、きちんと指定した値で初期化されるようになった。アクセス方法は、クラス名::$変数名となる。Hoge::$my_static;?>■統一コンストラクタオブジェクトが生成される際、自動的に呼ばれるメソッドを「コンストラクタ」という。PHP4のコンストラクタは、クラス名と同名のメソッドだった。これはJavaやC++と同じ仕様なので、そちらに慣れている人には違和感がないのだが、子クラスから親クラスのコンストラクタを呼びたい場合、Javaでいうsuper()が存在しないPHPでは親クラスの名前をわざわざ書かなければならない。PHPでは親クラスのコンストラクタは自動的に呼ばれないので、そうしたケースは比較的多い。そこでPHP5では、__construct(注)という統一コンストラクタ名を採用した。クラス名にかかわらず、__construct()というメソッドがコンストラクタとして扱われる。【注】__constructの「__」は、「_」が2つ連続している。以下に登場する「__」も同様。PHP4との互換性のため、クラス名と同名の従来のコンストラクタが存在すれば、そちらが優先して使用される。SubClass();?>■デストラクタコンストラクタとは逆に、オブジェクトが消滅するときに自動的に呼ばれるメソッドを「デストラクタ」という。PHP4ではデストラクタはサポートされておらず、register_shutdown_function()でPHPの実行終了時に呼び出される関数を登録することにより、疑似的に実現するしか方法がなかった。PHP5では正式にデストラクタがサポートされ、クラスごとにオブジェクトの消滅時の振る舞いを指定できるようになった。デストラクタは、__destructという名前のメソッドになる。オブジェクトの内部的な参照カウンタが0になると、__destruct()メソッドが呼び出され、その後でオブジェクトが保持しているメモリ領域が解放される。MyDestructableClass();?>なお、コンストラクタがそうであるのと同様に、親クラスのデストラクタが自動的に呼び出されることはない。必要な場合は、parent::__destruct();と記述して、明示的に呼び出してやる必要がある。■アクセサPHP4では、存在しないプロパティへアクセスが発生すると、自動的にそのプロパティを生成することで対応していた。property";のように、存在しないプロパティに値を代入しようとすると、代入時点でそのプロパティが生成される。同様に、存在しないプロパティの参照も、(Warning付きではあるが)null値が代入された変数があるかのように振る舞い、決してエラーになることはない。PHP5ではこれに追加して、任意のプロパティへのアクセスを制御できる仕組みが導入された。クラスに__set()、__get()というメソッドが存在すると、上記の振る舞いの代わりにこれらのメソッドが呼び出される。'789';?>ここでは、__setメソッドは引数をプリントした後にそのままプロパティとして代入している。'123';で$obj->aに値を代入しているが、この時点ではプロパティaは存在しないので、代わりに__setメソッドが呼び出される。123)と表示されるはずだ。'456';ともう一度$obj->aに代入している。今度は先ほどの代入でプロパティaが存在するので__setメソッドは呼び出されず、通常のプロパティ代入となる。789)と表示されるだろう。__getメソッドは、__setとは逆で、存在しないプロパティへの参照を上書きする。__setと__getを組み合わせると、プロパティへのアクセスのように見えて、実は全然違う場所に影響を与えるクラスを作成することができる。$obj->b;print_r($obj);?>この例では、クラスHogeのすべてのプロパティアクセスを$propertiesという配列に押し込めている。これはオブジェクト直下のプロパティをあまり使わないだけで、何がうれしいのかよく分からない例だが、この保存先を例えばファイルやDBに変えてみたりするのも面白いだろう。オブジェクトに何げなくアクセスしているように見えて、実は裏ではたくさんのコードが動いているということが簡単に実現できる。__set、__getとは多少趣が違うが、__callという、存在しないメソッドを上書きするものも用意されている。Class::methodname()というエラーになる。__callというメソッドがそのクラスにある場合、代わりに__callが呼び出される。__callの引数は2つで、第1引数は呼び出されたメソッド名、第2引数は呼び出し時の引数を保持した配列だ。使い方はいろいろ考えられるが、例えば以下のようにほかのオブジェクトへ呼び出しを委譲するといったことができる。PHP4のサポートが終了し、いよいよPHP5への移行を視野に入れる時期が来た。PHP4のサポートが完全に終了する。企業のWebアプリケーション開発現場で利用されるPHP。PHPは本当にダメな言語なのだろうか。World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。(2017/7/6)日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。Excel」で使えるVBAを紹介する。