オブジェクト指向のPHPはクラスとオブジェクトをサポートしている。以下にクラス等オブジェクトの例をあげる。<?phpclass abc{ var $a = null; function b(){ echo "abcクラスbメソッド?n"; return "戻値:abc->b"; } function abc(){ echo "abc:コンストラクタ生成?n"; } }class def extends abc{ function def(){ echo "def:コンストラクタ生成 > "; echo "def再定義メソッド(継承):" . parent::b() . "?n"; } function b(){ echo "オーバーライドされたbメソッド?n"; } } $c = new abc();abc::b();$f = new def();$f->b();?>
PHPに於けるコンストラクタ生成の演算子はnewである。extendsでクラスの継承が可能であるが多重継承はサポートされていない。varはおなじみだが、メンバ変数を宣言し定義する。echoは続くオブジェクトを出力するPHPの文書構造である。そのほかにもlist(配列)、final(メソッド)、private・public・protected(アクセス権)などの文書構造がある
parentは継承されたメソッドが、インスタンスされオーバーライドされた結果、継承されなかったメソッドを参照出来る。ここでdefクラスに継承されたメソッドはabc->bメソッドであり、def->bメソッドにより上書きされている。出力結果は以下の様になる。abc:コンストラクタ生成abcクラスbメソッドdef:コンストラクタ生成 > abcクラスbメソッドdef再定義メソッド(継承):戻値:abc->bオーバーライドされたbメソッド
アクセス権やfinalはPHP 5で導入された概念である(一部除く)。finalはメソッドを子クラスで上書きすることを禁止する構造である。
上記コードのインスタンス化されていないabc::b();でスコープ解決されたメンバ部分は、PHP5ではアクセス権の問題でアクセス出来ない。この場合、インスタンス化せずに呼び出したいので、// static:class abc{ var $a = null; static function b(){ ---------------------
とstatic宣言をせねばならない。宣言がない場合、全てpublic(どこからでも参照可)で処理される。
なおvarは互換性のため残されており、publicと等価であるが、PHP5.1.3以前のPHP5はエラーとなる。protectedは親クラス・派生クラス・ないしそれを実装するクラス自身からのアクセスのみを許可し、privateは定義クラス内部のみ参照が可能である。
抽象化はPHP 5より導入された概念であり、インタフェースはJavaのそれやObjective-Cので実装されているものである。 Objective-Cと違い、インタフェースはいまのところこれはコードから定義部と実装部を完全に切り離すものではなく、定義の必要性は無い。
やっていることは抽象クラス(抽象メソッド)とインターフェースは実質変わらないが、その概念は異なる。
インターフェースはその処理内容を定義せずに定義されるが、抽象クラス(抽象メソッド)は実装部の具体的な処理のコードと共に定義されている。
まず最初に具体的なソースコードを示す。<?phpinterface classTemplates { public function methodAlpha($arg1, $arg2); public function methodBeta($arg1); } class appTemplate implements classTemplates { public function methodAlpha($arg1, $arg2) { } public function methodBeta($arg1) { } }?>
interface接頭辞をつけテンプレートを定義し、implementsをつけクラスに適用し実装する。テンプレートはextends で継承可能である。 テンプレートは定義されていても必ず適用されるクラスが必要なわけではない。ただし、適用する前に定義されている必要がある。
いまのところ、定義できるのメンバはpublic(公開可視性)のあるメソッドだけである。
適用されたクラスに定義されたメソッドの「アクセス権・引数」が異なればエラーを引き起こし、またクラスの名前と同じinterfaceは定義できない。
インタフェースの継承
<?phpinterface classTemplatesModel { public function methodAlpha($arg1, $arg2); public function methodBeta($arg1); } interface classTemplates extends classTemplatesModel { public function methodGamma(); }?>
interfaceの多重継承について
今のところ、多重継承は出来ない。よって以下のコードは無効である<?phpinterface classTemplatesModel { public function methodAlpha($arg1, $arg2); public function methodBeta($arg1); } interface classTemplates extends classTemplatesModel { public function methodGamma(); } // このようなimplementsの実装は無効。class appTemplate implements classTemplates, classTemplatesModel { public function methodAlpha($arg1, $arg2) { } public function methodBeta($arg1) { } public function methodGamma() { } }?>
クラス名にfinalと同じ様に接頭辞としてabstractをつければ、それは抽象クラスとなる。
メソッドにつければ、それは必ず継承したクラスで実装されねばならない(引数は同じである必要がある)。具体的なソースを示す。<?phpabstract class Alpha { abstract public function methodAlpha($arg1, $arg2); protected function methodBeta($arg1) { echo "Alpha クラスで実装されたmathodBeta メソッド?n"; } public function __destruct() { echo "インスタンスを破棄、メモリを開放[Alpha::destruct]?n"; } } class Beta extends Alpha { public function __construct() { $this->methodAlpha("",""); $this->methodBeta(""); } public function methodAlpha($arg1, $arg2) { echo "Beta クラスで実装されたmethodAlpha メソッド?n"; } } new Beta();?>
__construct()は PHP 5からインスタンス生成の時に自動的に呼び出されるコンストラクタ(__destruct()、デストラクタも実装された)。
protected(保護可視性)は、継承されたクラス・または内部($this、parentなど)でないと、使えないようにする宣言である。
抽象化されたクラスはインスタンスを生成出来ない。よってnew Alpha();とすることは出来ない。また、抽象化されたメソッドは継承しないと使用することは出来ない。
実行結果
Beta クラスで実装されたmethodAlpha メソッドAlpha クラスで実装されたmethodBeta メソッドインスタンスを破棄、メモリを開放[Alpha::destruct]
詳細はPHP Data Objectを参照
MySQLやPostgreSQLなど主要なRDBMSへの接続については、それぞれ専用の関数ライブラリが用意されている。phpinfo()を表示させれば、そのPHPバージョンにおけるインプリメント状況を確認できる。関数の仕様については微妙な差があり、異なるRDBMSへの移行には支障となる。そのリスクを軽減するのがPDO(PHP Data Object)と呼ばれる、共通する機能はなるべく同じインタフェースで実現しようというアイデアによる、抽象化ライブラリである。ただし文字列処理関数などSQLごとに存在している差異までカバーしているわけではなく、移行に際してはそれなりの注意が必要である。いくらか楽になるという程度の認識で、過信は禁物といえよう。RDBMSごとに、pdo_から始まる名称のドライバモジュールが提供されているが、最近のPHP5.2.5などドライバモジュールが見当たらなくても、標準で組み込まれているケースがある。