2011-01 << 2011-02 >> 2011-03

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 にも解析ツール入ってるみたいですが,どの程度使えるのかなぁ.

2011-01 << 2011-02 >> 2011-03