php 5.4 用のシステムを 5.2 で動く様にする
PHP5.4向けの自作フレームワークで作成したシステムが、
納品直前でサーバがPHP 5.2であることが判明しました。
結局エンジンを5.2用に改造することになったのですが、
かなり手間がかかりましたので、今後のために要点を記録しておきます。
無名関数が使えないので、これはひたすらに外だし。
上記にも関連しますが、spl_autoload_register()に関数の直指定ができないため、
これを外だし。
1 2 3 |
spl_autoload_register(function($class_name){ ~include_once なんちゃら~ }); |
などとやっていたのを、
1 2 3 4 5 |
spl_autoload_register( 'xxx_autoload' ); function xxx_autoload( $class_name ) { ~include_once なんちゃら~ } |
のように改造
1 2 |
$class_name = "CTest"; $class_name::func( "arg" ); |
が出来ない。これらは全部、call_user_func() で代用する。
1 |
call_user_func( array($class_name, "func"), "arg" ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class BASE{ static function func(){ get_called_class()::core(); } static function core(){ echo 'BASE'; } } class A extends BASE { static function core(){ echo 'A'; } } class B extends BASE { static function core(){ echo 'B'; } } A::func(); // ← Aがechoされることを期待 B::func(); // ← Bがechoされることを期待 |
上記コードが動きません。
ネットで探すと、debug_backtrace()をパースする方法が代替メソッドとして例がいくつかありましたが、
どれもこれも完全には動作しませんでした。
そんな中、デフォルト引数に __CLASS__ を渡すという方法で
対処する手法が紹介されているのを見つけました。
http://qiita.com/Hiraku/items/2f4e3c146857010b4ff6
これすごいな!と感動し、試してみました。
サイトにも書かれていますが、上記コードを例にとると、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class BASE{ static function func( $called_class_=__CLASS__ ){ call_user_func( array($called_class_, core) ); } static function core(){ echo 'BASE'; } } class A extends BASE { static function func( $called_class_=__CLASS__ ){ return parent::func( $called_class_ ); } static function core(){ echo 'A'; } } class B extends BASE { static function func( $called_class_=__CLASS__ ){ return parent::func( $called_class_ ); } static function core(){ echo 'B'; } } A::func(); // ← Aがechoされることを期待 B::func(); // ← Bがechoされることを期待 |
要は派生先に同名のメソッドを追加し、__CLASS__を親へ親へと渡していき、起因となるクラスを特定します。
ちょっと面倒くさいですが、debug_backtrace()を使うよりは確実と思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class BASE{ public function __get( $var_name_ ) { $prefix = get_called_class()::prefix(); return $prefix.'-var'; } } class A extends BASE { public static function prefix() { return "AVAR"; } } class B extends BASE { public static function prefix() { return "BVAR"; } } $obj = new A(); echo $obj->unknown; // ← "AVAR-var" を期待 |
が動きません。
4.の方法をそのまま適用すると、
1 |
public function __get( $var_name_, $called_class_=__CLASS__ ) |
という定義になり、「ゲッターに引数二つ指定できないぜ」と言われます。
仕方がないので、継承先クラスに BASE のゲッターをそのままコピペしました…。
いい代替法があるのだろうか?
これが一番悩みました。
$_GETは受け取れる。しかし、$_POSTがどうしても空になってしまう。
なんで???と、悩むこと丸一日。
1 2 3 4 5 |
<form method="post" action="test.php"> <input type="text" name="var"> <input type="submit"> </form> <?php var_dump($_POST) ?> |
これで、内容が空になってしまうという…。
最終的に、.htaccessを消してみたら動いたので解決。
1 2 |
#POSTデータの最大サイズ php_value post_max_size 2G |
と書いていたのがまずかったようで、
“2G”を、”100m”に変更したら取得できるようになりました。
Gという単位が使えないのか、もしくはwin32バージョンだからなのか…
理由までは追いませんでしたが。
これでなんとか動作させることが出来、
5.3以上のありがたみを改めて実感したところです。