PHPでメタプログラミング 可変なお話
PHPはWeb特化言語という特性上他の言語では見られない強力な仕組みがあります。その特徴は他の言語では参照で取り回すところを文字列で取り回すところである、と言えるでしょう。
参照そのものを取り回す仕組みは便利なことも多いのですが、現在Webサイト周りのネットワークのプロトコルは処理系とは無関係な文字ベースのクエリーから成り立っており、特定の処理系に依存したバイナリではありません。なので参照前提の仕組みではどこかで文字から参照への変換をしないといけなくなり、たいていの言語でそのあたりがどうしても複雑になります。
ですが、PHPでは文字列が前提の仕組みが多くあり、無理なく取り回すことができます。
いい例が、関数を文字列として指定して呼び出せる可変関数と呼ばれている仕組みです。PHPは文字列が入った変数の後ろに()をつけると、その文字列に相当する名前を持つ関数を呼び出してくれる機能があるので、こんなことができます。
<?php $target="test"; $target();//test function test(){ echo "test"; } ?>
もちろん、これ自体ではたいしたことはできません。しかし、クラスと組み合わせるとこんなことができてしまいます。
<?php $target="test"; $check=new $target();//クラス「test」のコンストラクタが呼ばれ、"test"と表示される echo $check->tester; //hoge class test{ public $tester="hoge"; function __construct(){ echo "test"; } } ?>
PHPのフレームワークは、これを基本としています。他の言語におけるライブラリ、あるいはモジュールに相当するものを動的にロードするのが非常に容易なので、クエリーに適当な処理をして最初に呼び出すべき命名規則に基づいてロードすべきファイルと生成すべきファイルを定め、ロードしてオブジェクトを生成、という流れが必ず基点にあります。
可変変数を使おう
もうひとつの「可変」として、可変変数という変数名を文字列で指定する仕組みがあります。
PHPでは変数の頭に「$」記号がつくのですが、ここでさらに$をもうひとつ増やすか{}で閉じるとその名前の変数にアクセスできるので、こんなことができます。
<?php //基本 $target="test"; $test="target"; echo $$test;//test //クラスと組み合わせ1 メンバ変数へのアクセス class tester_a{ public $a=null; public $b=null; public $valid=array("a","b"); function __construct($params){ foreach($this->valid as $k){ $this->{$k}=$params[$k]; } } } $params=array("a"=>"a","b"=>"b"); $check=new tester_a($params); echo $check->a;//a echo $check->b;//b //クラスと組み合わせ2 クラスメソッドへのアクセス class tester_b{ function a(){ echo "a"; echo "\n"; } function b(){ echo "b"; echo "\n"; } public $valid=array("a","b"); function __construct(){ foreach($this->valid as $k){ $this->{$k}();//メソッドにアクセス } } } $check=new tester_b()//a,b; ?>
このように可変変数や可変引数を組み合わせるだけでも、少ないコード量でかなり複雑なことが可能になります。参照を取り回すことに慣れている人にとっては気持ち悪いかもしれませんが。