LoginSignup
4
0

More than 1 year has passed since last update.

歴史あるPHPプロダクトで少しでも開発を楽にしたい

Last updated at Posted at 2022-12-10

はじめに

古いPHPで書かれた古いプロダクトの保守をしているといろいろと大変なことがあります。
例えば、メソッドや変数に型情報がないためコードを読んだり書いたりするのにも以下のようなことから一苦労です。

  • コード補完がきかない
  • コードジャンプもきかない

少しだけ手間をかけることで、ちょっとでもコードを読み解きやすくしたいと思います。

環境

ご長寿

  • PHP 5.3
  • Symfony 1.4
  • Doctrine 1.2
  • PhpStorm

PhpStorm は素の状態です

PHPDoc を書く

PHPDoc とは

簡単に言うと、メソッドやクラスなどに定義上明記されていない情報を特別な記法でコメントに書くことで IDE などが解析しやすくするものです。
機械が解析できるようにすることで、ドキュメントを自動生成できるようになります。

この記事では変数の型やその説明が書ける、と理解してもらえれば良いです。

実際に書いてみましょう。

メソッドに書く場合

メソッドにはこんなのが書けます。

  /**
   * Counts the number of items in the provided array.
   *
   * @param mixed[] $items     Array structure to count the elements of.
   * @param bool    $recursive Optional. Whether or not to recursively
   *                           count elements in nested arrays.
   *                           Defaults to `false`.
   *
   * @return int Returns the number of elements.
   */
  public function count($items, $recursive = false)
  {
    <...>
  }

ここで見てほしいのは @param@return です。

@param

引数に関する情報を書きます。

@param [型] [名前] [説明]

重要なのは [型][説明] です。
[型] には int のようなプリミティブ型やクラスなどを書きます。
型について詳しくはこちらで↓確認できます。

[説明] には引数にどんなものを渡してほしいのかなどを簡潔に書くと良いです。

@return

返り値に関する情報を書きます。
名前がないこと以外は @param と同様です。

@return [型] [説明]

先程のメソッドを呼び出してみましょう

$this-> と打ち込んだところで候補に count が出てきました。
ここまでは PHPDoc コメントがなくても出てくると思います。

countが補完されている様子

ここで count を選択してみます

なにか出てきました。

こんなこと↓が書いてあるようですね

  • 上段 : 引数の名前: 引数の型
  • 下段 : 引数の説明

引数の説明のところを丁寧に書いておくと
呼び出すときにどんなものを渡せば良いのかが、わざわざ定義を読まなくてもわかります。
嬉しい。

ちなみに PHPDoc コメントを書いていないと

こうなります

型が類推できる場合はでてくることもありますが、説明は当然ながらありません。
items に何を渡すべきなのかを知るには count() の定義を確認する必要がありそうです。

直接 Doc コメントが書けないメソッドもある

すべてのメソッドに PHPDoc コメントを書きましょう
といいたいところなんですが、そうわけにいかないこともあります。
歴史あるプロダクトには一筋縄ではいかない場合もあったりするのです。

例えば古い Symfony + Doctine なプロダクトを泳いでいるとこんなものに遭遇することがあります。

$segment = SomeSegmentsTable::getInstance()->findOneBySomeUserStatus($user->getStatus());

どうやらこの findOneBySomeUserStatus というメソッドには PHPDoc コメントは書かれていないようです。
ここままだと $segment を使うときに補完がききません。
困った。

渋々定義を確認しようとします

が、よく見ると定義がありませんとあります。

まさかと思って確認しますが確かに SomeSegmentsTable クラスには書いてありません。

SomeSegmentsTable.class.php
<?php

/**
 * SomeSegmentsTable
 * 
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class SomeSegmentsTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object SomeSegmentsTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('SomeSegments');
    }
}

これだけ。

詳細は割愛しますが、 findOneBySomeUserStatus はマジックメソッドで、 Doctrine 本体で定義されています。
ライブラリのコードなので、自分で Doc コメントを書き加えたりするわけにもいかないでしょう。

しかしこのままではどうしても嫌なのでなんとかしてみます。

変数に書く場合

先程のこちら、

$segment = SomeSegmentsTable::getInstance()->findOneBySomeUserStatus($user->getStatus());

詳しいことは省きますが、
findOneBy~~ はデータベースからデータを1件取得してくれます。
この例ではデータを1件分のクラスは SomeSegments です。

こんなとき、この変数 $segment に対してこのように PHPDoc コメントを書きます。

/** @var SomeSegments $segment This is user segment. */
$segment = SomeSegmentsTable::getInstance()->findOneBySomeUserType($user->getType());

// もしくはこう↓書く

/**
 * This is user segment.
 * 
 * @var SomeSegments $segment
 */
$segment = SomeSegmentsTable::getInstance()->findOneBySomeUserType($user->getType());

@var

1行で書く場合

/** @var [型] [変数名] [説明] */

複数行で書く場合

/**
 * [説明]
 *
 * @var [型] [変数名]
 */

先程の変数を使ってみます

ちゃんと補完してくれますね。
嬉しい。

ただしメソッドの正体は謎のままです

そんなメソッドはありませんよ、と言われる。

ちょっとモヤモヤしますが、気にしなければ先へ進むことができます。
気にしていられないことも多いのでこのまま突き進むこともよくあります。

クラスに書く場合

上述のように呼び出す度に書いても良いんですが、よく使う場合はちょっと邪魔くさく感じるかもしれません。
そこで、先程の定義が書いてあることを期待したけど書いてなかったクラス、
こちらに Doc コメントを書くこともできます。

@method を使います。

SomeSegmentsTable.class.php
/**
 * SomeSegmentsTable
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 *
 * @method SomeSegments findOneBySomeUserType(string $someUserType)
 */
class SomeSegmentsTable extends Doctrine_Table

@method

@method [[static] 返り値の型] [名前]([[引数の型] [引数]<, ...>]) [説明]

改めて呼び出し側をみてみましょう

今度は変数の Doc コメントがなくても補完されます。
いいですね。

メソッドの型定義もわかります。
すばらしい。

まとめ

これだけのことでも少しは息ができるようになりました。

おまけ

VSCode の場合は Extention を入れると同じように補完してくれるみたいです。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0