HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

Eclipse(PDT)でPHPのコードを書く時の不便さを解消する

そもそも、静的型付けでない言語は好きではないのですが、好き嫌いを言っていると仕事が無くなってしまうので・・

そんなわけで、Eclipse(PDT)でPHPのコードを書くわけですが、時にあるクラスのインスタンスの配列を関数/メソッドに渡す形にしたい時があります。

<?php
class A {
  /**
   * ID
   * @var int
   */
  public $id;
  /**
   * 名前
   * @var string
   */
  public $name;
}
<?php
function a0(array $a) {
    foreach ($a as $aa) {
        // A のインスタンスである保証がないし、
        // Eclipseで変数名候補を表示させたりできない(重要!!)
        var_dump($aa->name);
    }
}

この時、関数「a0」内の変数「$aa」が何であるかという保証は何もありませんので、何らかのチェックをする必要があります。

PHPにはtype hintingという機能があり、以下のように書ければいいのですが・・

<?php
// 実際にはエラーになる
function a0(A[] $a) {
    // ・・・
}
<?php
// 実際にはエラーになる
function a0(multitype:A $a) {
    // ・・・
}
<?php
// 実際にはエラーになる
function a0(array(A) $a) {
    // ・・・
}

そんなわけで、Eclipse(PDT)をだますために、ひと工夫したりします。

instanceofで判定する

<?php
function a1(array $a) {
    foreach ($a as $aa) {
        if ($aa instanceof A) {
            var_dump($aa->name);
        }
    }
}

こうすると、「$aa」はクラスAのインスタンスであることが保証されるので、Eclipse(PDT)がそれを解釈して「$aa」をクラスAのインスタンスとして変数名候補の列挙などをしてくれます。

フィルタ用の関数を作る

<?php
function a2(array $a) {
    $a = filterA($a);
    foreach ($a as $aa) {
        var_dump($aa->name);
    }
}
/**
 *
 * @param array $a
 * @return multitype:A
 */
function filterA(array $a) {
    $res = array();
    foreach ($a as $aa) {
        if ($aa instanceof A) {
            $res[] = $aa;
        }
    }
    return $res;
}

ポイントは、関数「filterA」のdocument comment内の「@return multitype:A」です。 この関数を通してやることにより、戻り値がクラスAのインスタンスであることが一応保証されるので、Eclipse(PDT)をだますことができます。


実際のところ、皆さんはこの問題をどうやって乗り越えているんでしょうか・・