2011-02-10 (木)
*PHPのコードを静的に型チェックしてみた
PHP -lとか使い物にならないし,フリーで良さげなツールが見つからないので仕事の合間に作ったやつを.
<?php /** * @return Hoge */ function getHoge() { return null; } $hoge = getHoge(); /* !info $hoge */ class Foo{} class Hoge { /** * @var Foo */ public $hoge; /** * @return string */ public function getBar() { return '1234567\'afafa'; } /** * @param Foo $a * @return Hoge */ public function getHoge($a) { return null; } } $h = new Hoge(); $h2 = $h->hoge; /* !info $h */ /* !info $h2 */ /* @var $a int */ $a = "aaa\"123\n"; $b = 234; $c = $a; $d = $h->getBar(); /* !info $a */ /* !info $b */ /* !info $c */ /* !info $d */ $h->getHoge(null,null); $hoge = $h->getHoge(new Hoge())->getBar(); /* !info $hoge */
これをチェックするプログラムに入れると,
start /test.php line:10 INFO: $hoge is Hoge line:39 INFO: $h is Hoge line:40 INFO: $h2 is Foo line:44 WARN: Type mismatch $a: int -> string line:47 INFO: $a is string line:48 INFO: $b is int line:49 INFO: $c is string line:50 INFO: $d is string line:52 ERROR: Too many arguments for Hoge::getHoge(1) line:53 WARN: type mismatch param(1): Hoge -> Foo line:54 INFO: $hoge is string ok.
という結果が出力されます.INFOはデバッグ用に型を表示してるだけです.出力は簡素なテキストかHTMLか選べます.
PHPDocコメントで定義している型と違うものを代入した場合や,関数の引数の型が違う場合も警告出してくれます.
まぁ,ちゃんとテストしてれば動作に問題は無いのですが,コメントに書いてあることが嘘だったり,メソッド呼び出し時のパラメータが多すぎたりとかがあると,後で勘違いの元凶になるのでどうにかしないとです.
まだ演算子の処理がいい加減なのと,配列がチェックできてないので,もう少しいじる必要がある.
とりあえず,定期的にリポジトリ内のコードをチェックするようにcronに入れておく.
PSATとか,PHPCodeAnalyzerとかがあるようですが,少し調べた感じだと,まだ実用に足るものではなさそうです.Zend Studio にも解析ツール入ってるみたいですが,どの程度使えるのかなぁ.