タイトル: コメント
SEOタイトル: PHP コメント完全ガイド (// / # / /* */ / PHPDoc)
| この記事の要点 |
- PHP のコメントは
// 1 行 / # 1 行 / /* 複数行 */ / /** PHPDoc */ の 4 種 - PHPDoc
/** ... */ は IDE 補完・静的解析 (PHPStan/Psalm) の型情報源として活躍 - 主要タグ:
@param / @return / @throws / @var / @deprecated / @see / @since - PSR-5 が PHPDoc の仕様 (Draft)、phpDocumentor でドキュメント自動生成
- アンチパターン: 「コメントで挙動を説明する」より「関数名 / 変数名で表現」。コメントは"why"を書く
|
4 種類のコメント構文
<?php
// 1 行コメント (C / Java スタイル)
echo 'hello'; // 末尾コメント
# 1 行コメント (Bash / Perl スタイル) - PHP 独自
echo 'hi'; # こちらも有効
/*
複数行コメント
ブロックコメント
*/
/**
* PHPDoc 形式(IDE / 解析ツール対応)
*
* @param string $name 名前
* @return string 挨拶文
*/
function greet(string $name): string {
return "Hello, $name";
}
PHPDoc の主要タグ
| タグ | 用途 | 例 |
@param | 引数の型と説明 | @param int $id ユーザー ID |
@return | 戻り値の型と説明 | @return User|null |
@throws | 投げる例外 | @throws NotFoundException |
@var | プロパティ / 変数の型 | @var array<int, User> |
@deprecated | 非推奨マーク | @deprecated 1.5 use bar() |
@see | 関連参照 | @see User::find() |
@since | 追加バージョン | @since 2.0.0 |
@author | 作成者 | @author Taro <taro@example.com> |
@link | 外部参照 URL | @link https://example.com/docs |
@template | ジェネリクス (Psalm/PHPStan) | @template T of Model |
@internal | 内部使用専用 | — |
関数コメントの実例
<?php
/**
* ユーザーを ID で検索する
*
* 削除済ユーザーは含まれない。
* キャッシュは 5 分間有効。
*
* @param int $id ユーザー ID(1 以上)
* @param bool $withTrash 削除済も含めるか
* @return User|null 見つからなければ null
* @throws InvalidArgumentException $id が 0 以下のとき
* @see UserRepository::findByEmail() メールで検索
* @since 1.2.0
*/
public function find(int $id, bool $withTrash = false): ?User {
if ($id <= 0) {
throw new InvalidArgumentException('id must be positive');
}
// ...
}
クラス / プロパティコメント
<?php
/**
* ユーザーリポジトリ
*
* DB から User Entity を取得する。
*
* @package App\Repositories
* @author Taro Yamada
*/
class UserRepository
{
/**
* @var array<int, User> ID → User のキャッシュ
*/
private array $cache = [];
/**
* @var \PDO データベース接続
*/
private \PDO $pdo;
/** @var int キャッシュ有効秒数 */
private const TTL = 300;
}
静的解析ツールとの連携
| ツール | 役割 | PHPDoc 活用 |
| PHPStan | 静的解析・型チェック | ジェネリクス / 配列 shape 推論 |
| Psalm | 静的解析・型チェック | 厳密な型推論 |
| PhpStorm / VS Code | IDE 補完 | 引数 / 戻り値ヒント |
| phpDocumentor | API ドキュメント生成 | HTML 出力 |
| Doctum / Sami | ドキュメント生成 | Symfony / Laravel 系で人気 |
PHPDoc 専用の型表現
<?php
/**
* PHPDoc では PHP の型システムを超えた表現が可能
*
* @param array<int, string> $names キー int、値 string の配列
* @param array<string, int> $scores キー string、値 int
* @param list<string> $tags 0 始まり連番の配列
* @param array{name: string, age: int} $user shape 指定
* @param 'asc'|'desc' $order リテラル型 (PHP 8.1+ Enum 代替)
* @param int<1, 100> $page 範囲指定
* @param non-empty-string $title 空文字不可
* @return Generator<int, User> 戻り値の Iterator 中身
*/
function search(array $names, array $scores, array $tags, array $user, string $order, int $page, string $title): \Generator {
// ...
}
コメントのアンチパターン
<?php
// ❌ コードを日本語で繰り返すだけ
$i = 0; // i に 0 を代入
$i++; // i をインクリメント
// ❌ 嘘コメント(リファクタで挙動が変わってもコメントが残る)
// ユーザーをメールで検索
function findByName(string $name) { /* メールではなく名前で検索している */ }
// ❌ コメントアウトで残されたデッドコード
// $oldLogic = ...;
// if ($oldLogic) { ... }
// ✅ Why を書く(なぜそうしたか)
// 業務要件: 0 円商品も「購入済」扱いにする (#1234)
if ($price >= 0) {
$order->markAsPaid();
}
// ✅ TODO / FIXME / XXX (IDE で抽出可能)
// TODO: PHP 8.2 で readonly class に置き換え
// FIXME: タイムゾーン考慮漏れ
他言語との対比
| 言語 | 1 行 | 複数行 | ドキュメント |
| PHP | // # | /* */ | PHPDoc /** */ |
| JavaScript | // | /* */ | JSDoc /** */ |
| Java | // | /* */ | JavaDoc /** */ |
| Python | # | ''' ''' | docstring + Sphinx |
| Ruby | # | =begin =end | YARD / RDoc |
| Go | // | /* */ | godoc (コメント自体) |
FAQ
Q: // と #、どちらを使うべき?
A: PSR-12 では特に規定なし。チーム慣習に従う。一般的に // が多数派です。
Q: PHPDoc は書かないとダメ?
A: 型宣言 (PHP 7.0+) で補えれば省略可。ただし配列の中身 / ジェネリクス / 例外は型宣言で表現できないため PHPDoc が役立ちます。
Q: コメントは何語で書く?
A: チーム共通言語で。OSS は英語推奨。日本国内クローズドなら日本語 OK。混在は避ける。