はじめに
PHPDocって「大事なのは分かるけど、何をどう書けばいいか迷う…」となりがちな技術の代表格ではないでしょうか。結果、人によって書き方がバラバラだったり、そもそも書かれなかったり…。
この記事は、そんな「PHPDoc迷子」な自分のために、現場で本当によく使う記載パターンだけを厳選し、いつでも見返せるテンプレート集としてまとめました。
もちろん、一番大事なのはチームで決められたコーディング規約です。ただ、その規約を作る上でも、個人で開発する上でも、「良い書き方の引き出し」を持っておくことはとても重要かなと考えています。
結論:まずはこれだけ覚えればOK
細かい話は抜きにして、最低限これだけ押さえれば、PHPDocは十分にその価値を発揮します。
- 1行の短い説明: そのコードが「何をするのか」を簡潔に書く。
-
@param: 引数の「型」と「意味」を伝える。 -
@return: 戻り値の「型」と「意味」を伝える。 -
配列の書き方:
string[]やarray<string, mixed>で中身を表現する。 -
@throws(必要なら): どんな例外が起こりうるか伝える。
基本形はこれです。
/**
* 〇〇する
*
* @param type $name 説明
* @return type 説明
*/
ポイントは**「読む人が一瞬で理解できるか?」**を意識すること。IDEの補完や静的解析のためだけでなく、未来の自分やチームメンバーへの「思いやり」の気持ち(めっちゃ大事です)で書くと、自然と良いPHPDocになります。
【基本パターン編】迷ったらこれ!
まずは基本となる5つのパターンです。
1. 引数が1つの関数(すべての基本)
一番シンプルな形。型宣言とPHPDocを併記することで、「何のための引数か」が明確になります。
/**
* ユーザーIDから表示名を取得する
*
* @param int $userId ユーザーID
* @return string 表示名
*/
public function getDisplayName(int $userId): string
{
// ...
}
int 型なのは分かっていても、それが「ユーザーID」であるという 意味 が加わるだけで、コードの可読性は格段に上がります。
2. 引数が複数の関数
引数が複数になっても基本は同じです。引数ごとに @param を書きます。
/**
* 商品価格に税率を適用して税込価格を返す
*
* @param int $price 税抜価格
* @param float $rate 税率(例: 0.1)
* @return int 税込価格
*/
public function calcTaxIncluded(int $price, float $rate): int
{
// ...
}
$rate に (例: 0.1) といった補足説明を添えるだけで、10 を渡してしまうような間違いを減らせます。
3. 戻り値がない (@return void)
何かを返す必要がない関数の場合は @return void と書きます。
/**
* ユーザーの最終ログイン日時を更新する
*
* @param int $userId ユーザーID
* @return void
*/
public function updateLastLogin(int $userId): void
{
// ...
}
@return void を書くかどうかはチームの規約にもよりますが、「この関数は何も返さない」という意思を明確に示すために書くのがおすすめです。
4. Nullable (?User or User|null)
null を返す可能性がある場合は、そのことを明記します。
/**
* メールアドレスからユーザーを取得する
*
* @param string $email メールアドレス
* @return User|null 見つからない場合はnull
*/
public function findByEmail(string $email): ?User
{
// ...
}
PHPの型宣言 ?User とPHPDocの User|null は同じ意味です。どちらかに統一しましょう。(PhpStormなどは | 区切りを推奨することが多いです)
「どんな時に null になるのか」を一言添えると、使う側が null チェックを忘れにくくなり、とても親切です。
5. Union Type (string|int)
複数の型を受け入れる可能性がある場合は | で繋ぎます。
/**
* 入力値を文字列として正規化する
*
* @param string|int $value 入力値
* @return string 正規化された文字列
*/
public function normalize(string|int $value): string
{
// ...
}
これも型宣言とPHPDocを一致させることで、IDEのサポートを最大限に受けられます。
【配列編】PHPDocの真価はここにある!
PHPDocが最も輝くのが配列の型定義です。PHPの型宣言 array だけでは分からない「配列の中身」を表現できます。
6. パターン1: 値の配列 (string[])
一番よく使う、シンプルな配列の表現です。
/**
* @param string[] $names 名前一覧
* @return string[] 正規化済み名前一覧
*/
public function normalizeNames(array $names): array
{
// ...
}
Type[] と書くだけで、その配列が「何のリストなのか」が一目瞭然になります。
7. パターン2: キーと値の連想配列 (array<string, int>)
キーと値の型が分かっている連想配列には、ジェネリクス形式が便利です。
/**
* @param array<string, int> $scores ユーザー名 => スコア
* @return array<string, int> ソート済みスコア
*/
public function sortScores(array $scores): array
{
// ...
}
array<KeyType, ValueType> の形で表現します。
8. パターン3: オブジェクトの配列 (User[])
オブジェクトの配列を表現すると、IDEの補完がフル活用できます。
/**
* @param User[] $users ユーザー一覧
* @return int アクティブユーザー数
*/
public function countActiveUsers(array $users): int
{
foreach ($users as $user) {
// $user-> と入力すると、Userクラスのメソッドやプロパティが補完される!
}
// ...
}
9. パターン4: "構造"が決まった配列 (Array Shapes)
DTO(Data Transfer Object)を作るほどではないけれど、返す配列の構造が決まっている… そんな場面で絶大な効果を発揮するのがこの書き方です。
/**
* ユーザーの簡易情報を返す
*
* @param int $userId
* @return array{
* id: int,
* name: string,
* email: string|null
* }
*/
public function getUserSummary(int $userId): array
{
// ...
}
この array{...} という書き方(Array Shapes と呼ばれます)により、戻り値の配列にどんなキーが含まれ、それぞれの値がどの型なのかを厳密に定義できます。
静的解析ツールがキーのtypoを検出してくれたり、IDEがキー名を補完してくれたり、メリットしかありません。
【応用パターン編】もう一歩先の書き方
最後に、より安全で分かりやすいコードに繋がる応用パターンです。
10. 例外を知らせる (@throws)
処理中に例外を投げる可能性がある関数には @throws を書きましょう。
/**
* 注文を確定する
*
* @param int $orderId 注文ID
* @throws \RuntimeException 注文が見つからない場合
* @return void
*/
public function finalize(int $orderId): void
{
if (!Order::exists($orderId)) {
throw new \RuntimeException('注文が見つかりません');
}
// ...
}
これがあるだけで、この関数を使う側は try-catch で囲む必要があるかもしれない、と事前に察知できます。
11. 真偽値 (bool) の意味を明確にする
bool を返す関数は、true / false がそれぞれ何を意味するのかを必ず書きましょう。
/**
* ユーザーが課金中かどうかを返す
*
* @param int $userId ユーザーID
* @return bool 課金中ならtrue
*/
public function isPremium(int $userId): bool
{
// ...
}
if (isPremium($userId)) のようなコードの意味が、PHPDocを見るだけで明確になります。
12. 変数の中身を伝える (@var)
型推論が難しい場面では @var が役立ちます。特に、配列から取り出した値や、mixed 型の変数を扱うときに有効です。
/** @var array{id: int, name: string} $user */
$user = $this->fetchUserFromLegacyApi();
// これで $user['name'] のようなアクセス時にIDEの補完が効く
echo $user['name'];
コピペ用ミニテンプレート集
// 基本形
/**
* 〇〇する
*
* @param 〇〇 $〇〇 〇〇
* @return 〇〇 〇〇
*/
// 配列
/**
* @param Type[] $items 〇〇
* @return Type[] 〇〇
*/
// 連想配列
/**
* @param array<string, Type> $map 〇〇
* @return array<string, Type> 〇〇
*/
// 形が決まった配列 (Array Shape)
/**
* @return array{
* key1: Type,
* key2: Type|null
* }
*/
// 例外
/**
* @throws \Exception 〇〇の場合
*/
補足:型宣言とPHPDocの役割分担(最近の書き方)
近年は静的型付け言語の人気もあって、「型情報をコードに持たせて安全に書く」流れが強くなっています。PHPも型宣言(引数・戻り値・プロパティの型など)が充実してきたので、PHPDocは“型宣言の補完”として使うのが基本です。
(※PHPDocはあくまでコメントなので、実行時の型チェックを置き換えるものではありません)
実務では、だいたい次の使い分けが分かりやすいです。
-
PHPが表現できる型は、基本的に「型宣言」を優先
例:int/string/bool/?User/string|intなど -
PHPが表現しきれない型は「PHPDoc」で補う
例:配列の中身(string[]/array<string, int>)、Array Shape(array{...})、(必要なら)ジェネリクス相当の表現 など
また、プロジェクト規模やフェーズでも現実的な最適解は変わります。
- 新規開発なら:型宣言をできるだけ厚く(PHPDocは配列など“足りない部分”だけ)
- 既存の巨大PJに段階導入なら:まずPHPDocで安全性を底上げして、必要箇所から型宣言へ移行
大事なのは「どちらが正しい」ではなく、チームの規約と保守コストに合わせて“型情報を増やす”ことです。
まとめ
PHPDocは、完璧を目指すと疲れてしまいます。大切なのは 「型」と「意図」を補う こと。
特に優先すべきはこのあたりです。
-
@param(型と意味) -
@return(型と、null/boolの意味) - 配列の中身の表現
@throws
PHPDocは、書いた瞬間よりも、3ヶ月後に自分や他の誰かが見返した時に真価を発揮する「未来への投資」です。
この記事が、その投資を始めるきっかけになれば幸いです。
採用拡大中!
アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニア仲間を大募集しています!
少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう!
お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/