PHP4 と PHP5 で __get(), __set(), __call() を共存する方法
PHP5 では クラスの __get()、__set() および __call() をネイティブにサポートしています。
一方 PHP4 でも 4.3 以降 overload() を実行することで、クラスのオーバーロードを行うことが可能で、__get()、__set() および __call() を使用することができます。
しかしそれぞれのメソッドのインターフェース仕様が異なっているため、これらを普通に使用した対象クラスは PHP4 用もしくは PHP5 用という限定した存在になってしまいます。
しかし以下のようにすることで、PHP4, PHP5 の共存が可能になります。
例として Foo クラスにて __call() を実装してみます。
Foo.php
<?php
class Foo
{
var $x = 'foo';
function &singleton()
{
static $instance;
if (!isset($instance)) {
if (preg_match('!^5.d+.d+$!', phpversion())) {
require_once('Foo/PHP5.php');
$instance = new Foo_PHP5();
} elseif (preg_match('!^4.d+.d+$!', phpversion())) {
require_once('Foo/PHP4.php');
overload('Foo_PHP4');
$instance = new Foo_PHP4();
}
}
return $instance;
}
function ___call($func, $args)
{
print "function $func called
";
var_dump($args);
return $this->x;
}
}
?>
Foo/PHP4.php
<?php
class Foo_PHP4 extends Foo
{
function __call($func, $args, &$return)
{
if (strtolower($func) !== __CLASS__) {
$return = $this->___call($func, $args);
return true;
}
}
}
?>
Foo/PHP5.php
<?php
class Foo_PHP5 extends Foo
{
function __call($func, $args)
{
if (strtolower($func) !== __CLASS__) {
return $this->___call($func, $args);
}
}
}
?>
使用例
require_once('Foo.php');
$foo = Foo::singleton();
var_dump($foo);
var_dump($foo->try(1, 2, 3));
結果
= PHP4 の場合 =
object(foo_php4)(1) {
["x"]=>
string(3) "foo"
}
function try called
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
string(3) "foo"
= PHP5 の場合 =
object(Foo_PHP5)#1 (1) {
["x"]=>
string(3) "foo"
}
function try called
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
string(3) "foo"
*************************
もう見てのとおり、ひとつのクラスごとに PHP4 用と PHP5 用をそれぞれ準備しなければならず非常に面倒ですねっ!一応 __call() で行うべき処理内容を親クラスで記述できるのでロジックが分散するといったことはないのですけれども。
PHP4, PHP5 用ファイルを共通として使用したいところです。クラスの集約を行う関数として aggregate() があるんですがこれは PHP4 のみなので意味がないですし、PHP5 でも使える置き換え関数 runkit は PECL な罠。
トラックバック(0)
このブログ記事を参照しているブログ一覧: PHP4 と PHP5 で __get(), __set(), __call() を共存する方法
このブログ記事に対するトラックバックURL: http://hatotech.org/mt-admin/mt-tb.cgi/612

コメントする