php-guidelines-from-spatie について
php-guidelines-from-spatieは、PHPとLaravel開発向けのコーディングガイドラインスキルです。型宣言、命名、制御フロー、テスト、フレームワークの規約をまとめ、コードレビューや生成の基準を揃えたい開発者を対象としています。
主な機能
- 01PSR-1・PSR-2・PSR-12に準拠
- 02Laravelの規約を優先
- 03型宣言とDocBlockのルール
- 04命名規則とファイル構成
- 05テストとコード品質の実践事項
活用シーン
- 01Laravelの規約に沿ったコード作成
- 02PHPの命名や型の使い方をレビュー
- 03プロジェクトのテストと書式を統一
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ freekmurze/ dotfiles --skill php-guidelines-from-spatieインストール後、Claude Code で/php-guidelines-from-spatieを入力して読み込まれたか確認します。
詳細
Laravel の基本原則
まず Laravel の規約に従ってください。 Laravel に何かを行うためのドキュメント化された方法がある場合は、それを使用してください。明確な理由がある場合に限り、規約から外れてください。
PHP の標準
- PSR-1、PSR-2、PSR-12 に従ってください
- 外部公開されない文字列には camelCase を使用してください
- 短い nullable 記法を使用してください:
string|nullではなく?string - メソッドが何も返さない場合は、必ず戻り値の型に
voidを指定してください
クラス構造
- docblock ではなく、型付きプロパティを使用してください:
- すべてのプロパティを昇格できる場合は、コンストラクターのプロパティ昇格を使用してください:
- トレイトは1行に1つ記述してください:
型宣言と Docblock
- docblock よりも型付きプロパティを使用してください
voidを含め、戻り値の型を指定してください- 短い nullable 構文を使用してください:
Type|nullではなく?Type - ジェネリクスを使用して iterable をドキュメント化してください:
/** @return Collection<int, User> */ public function getUsers(): Collection
Docblock のルール
- 型ヒントが完全に指定されたメソッドには、説明が必要な場合を除き docblock を使用しないでください
- docblock ではクラス名を必ずインポートしてください。完全修飾名は使用しないでください:
use \Spatie\Url\Url; /** @return Url */ - 可能な場合は1行の docblock を使用してください:
/** @var string */ - 複数の型を記述する docblock では、最もよく使われる型を先にしてください:
/** @var Collection|SomeWeirdVendor\Collection */ - 1つのパラメーターに docblock が必要な場合は、すべてのパラメーターに docblock を追加してください
- iterable では、キーと値の型を必ず指定してください:
/** * @param array<int, MyObject> $myArray * @param int $typedArgument */ function someFunction(array $myArray, int $typedArgument) {} - 固定キーには配列シェイプ記法を使用し、各キーを独自の行に記述してください:
/** @return array{ first: SomeClass, second: SomeClass } */
制御フロー
- 正常系は最後に:まずエラー条件を処理し、成功ケースを最後に処理してください
- else を避ける:ネストした条件の代わりに早期リターンを使用してください
- 条件を分ける:読みやすさを高めるため、
&&を使用した複合if文はネストしたif文に分割してください - 1つの文だけの場合でも、必ず波括弧を使用してください
- 三項演算子:非常に短い場合を除き、各部分を別々の行に記述してください
// Happy path last
if (! $user) {
return null;
}
if (! $user->isActive()) {
return null;
}
// Process active user...
// Short ternary
$name = $isFoo ? 'foo' : 'bar';
// Multi-line ternary
$result = $object instanceof Model ?
$object->name :
'A default value';
// Ternary instead of else
$condition
? $this->doSomething()
: $this->doSomethingElse();
// Bad: compound condition with &&
if ($user->isActive() && $user->hasPermission('edit')) {
$user->edit();
}
// Good: nested ifs
if ($user->isActive()) {
if ($user->hasPermission('edit')) {
$user->edit();
}
}
Laravel の規約
ルート
- URL:kebab-case(
/open-source) - ルート名:camelCase(
->name('openSource')) - パラメーター:camelCase(
{userId}) - タプル記法を使用してください:
[Controller::class, 'method']
コントローラー
- リソース名は複数形にしてください(
PostsController) - CRUD メソッド(
index、create、store、show、edit、update、destroy)を使用してください - CRUD 以外のアクションには、新しいコントローラーを作成してください
設定
- ファイル:kebab-case(
pdf-generator.php) - キー:snake_case(
chrome_path) - サービス設定は
config/services.phpに追加し、新しいファイルは作成しないでください config()ヘルパーを使用し、設定ファイル以外ではenv()を避けてください
Artisan コマンド
- 名前:kebab-case(
delete-old-records) - 必ずフィードバックを提供してください(
$this->comment('All ok!')) - ループでは進捗を表示し、最後に要約を表示してください
- デバッグを容易にするため、処理対象の項目を処理する前に出力してください:
$items->each(function(Item $item) { $this->info("Processing item id `{$item->id}`..."); $this->processItem($item); }); $this->comment("Processed {$items->count()} items.");
文字列と書式
- 文字列連結よりも文字列補間を使用してください:
Enum
- Enum の値には PascalCase を使用してください:
コメント
コメントは時間の経過とともに古くなり、誤解を招くことが多いため、追加には十分注意してください。変数名や関数名を分かりやすくし、コード自体で説明できるようにしてください。
コードを読みやすくするために、コメントの追加を最初の手段にしてはいけません。
次のようにするのではなく:
// Get the failed checks for this site
$checks = $site->checks()->where('status', 'failed')->get();
次のようにしてください:
$failedChecks = $site->checks()->where('status', 'failed')->get();
ガイドライン:
- コードが何をしているかを説明するコメントは追加せず、コード自体が説明するようにしてください
- 短く読みやすいコードに説明コメントは不要です
- 汎用的な名前とコメントを組み合わせるのではなく、説明的な変数名を使用してください
- 明白でない処理を行う理由を説明する場合に限り、コメントを追加してください。処理の内容は説明しないでください
- テストにコメントを追加しないでください。テスト名だけで十分に説明できるようにしてください
空白
- 読みやすさのため、文と文の間に空行を追加してください
- 例外:同等の1行操作が連続する場合
{}の間に余分な空行を入れないでください- コードに余裕を持たせ、詰め込みすぎた書式は避けてください
バリデーション
- 複数のルールには配列記法を使用してください(カスタムルールクラスで扱いやすくなります):
public function rules() { return [ 'email' => ['required', 'email'], ]; } - カスタムバリデーションルールには snake_case を使用してください:
Validator::extend('organisation_type', function ($attribute, $value) { return OrganisationType::isValid($value); });
Blade テンプレート
- 4つのスペースでインデントしてください
- 制御構造の後にスペースを入れないでください:
@if($condition) Something @endif
認可
- ポリシーには camelCase を使用してください:
Gate::define('editPost', ...) - CRUD の用語を使用し、
showの代わりにviewを使用してください
翻訳
@langではなく__()関数を使用します。
API ルーティング
- リソース名は複数形にします:
/errors - ケバブケースを使用します:
/error-occurrences - シンプルにするため、深いネストは避けます:
/error-occurrences/1 /errors/1/occurrences
テスト
- 可能であれば、テストクラスは同じファイルにまとめます
- 説明的なテストメソッド名を使用します
- arrange-act-assert パターンに従います
- ヘルパー関数はテストファイルの末尾、
it/testブロックの下に置きます(まずテストを読めるようにし、ヘルパーは補助的な詳細として扱います)
クイックリファレンス
命名規則
- クラス:パスカルケース(
UserController、OrderStatus) - メソッド/変数:キャメルケース(
getUserName、$firstName) - ルート:ケバブケース(
/open-source、/user-profile) - 設定ファイル:ケバブケース(
pdf-generator.php) - 設定キー:スネークケース(
chrome_path) - Artisan コマンド:ケバブケース(
php artisan delete-old-records)
ファイル構成
- コントローラー:複数形のリソース名+
Controller(PostsController) - ビュー:キャメルケース(
openSource.blade.php) - ジョブ:アクションベース(
CreateUser、SendEmailNotification) - イベント:時制ベース(
UserRegistering、UserRegistered) - リスナー:アクション+
Listenerサフィックス(SendInvitationMailListener) - コマンド:アクション+
Commandサフィックス(PublishScheduledPostsCommand) - メールクラス:用途+
Mailサフィックス(AccountActivatedMail) - リソース/トランスフォーマー:複数形+
Resource/Transformer(UsersResource) - 列挙型:説明的な名前を付け、接頭辞は付けません(
OrderStatus、BookingType)
マイグレーション
- マイグレーションには down メソッドを記述せず、up メソッドのみを記述します
コード品質に関する注意事項
PHP
- Docblock より型付きプロパティを使用します
- ネストした if/else より早期リターンを優先します
- すべてのプロパティをプロモートできる場合は、コンストラクターのプロパティプロモーションを使用します
- 可能であれば
else文を避けます &&を使った複合if条件は、ネストしたif文に分割します- 文字列の連結より文字列補間を使用します
- 制御構文では必ず中括弧を使用します
- 名前空間は必ず
use文でインポートします。インラインで完全修飾クラス名(例:\Exception、\Illuminate\Support\Facades\Http)を使用してはいけません - 1 文字の変数名は使用せず、説明的な名前を付けます(例:
$eではなく$exception、$rではなく$request)
コメント
Markdown 対応