VS Codeで始めるPHP開発環境 と同じく、WSL2 + Docker と Remote - WSL 前提で進めます。
前提記事をまだ試していなくても、2章の最小構成ディレクトリで手順を追えます。
保存時自動整形は強制せず、手動整形のやり方だけをそろえます。
前提環境
- Windows 11
- WSL2(Ubuntu)
- VS Code(Remote - WSL)
- Docker Desktop(WSL連携有効)
以降のコマンドは、WSL 側プロジェクトディレクトリで実行します。
サービス名が app ではない場合は、読み替えてください。
1. ゴールと非対象
この記事で到達する状態:
docker compose exec app ...でphp-cs-fixerを実行できる--dry-run --diffで変更内容を確認してからfixを適用できる.php-cs-fixer.dist.phpと.editorconfigの役割を分けて運用できる
この記事で扱わない内容:
- PHPCS/PHPCBF の詳細運用
- PHPStan/Psalm/Rector の導入
- CI での強制整形
allow-riskyを使ったルール運用
2. 作業ディレクトリと Compose を作成する
ここから先のコマンドは、特記がない限り WSL ターミナルで実行します。
Windows 側の PowerShell / Windows Terminal から始める場合は、先に WSL へ入ります。
wsl
作業用ディレクトリを ~/projects 配下に作成して移動し、VS Code で開きます。
mkdir -p ~/projects/php-formatter-demo
cd ~/projects/php-formatter-demo
code .
compose.yml を作成します。
~/projects/php-formatter-demo/compose.yml
services:
app:
image: composer:2
working_dir: /workspace
volumes:
- ./:/workspace
command: ["sleep", "infinity"]
今回は整形手順の確認に絞るため、最小構成の composer:2 を使います。
実プロジェクトでは、アプリ本体と同じ PHP バージョンのイメージに置き換えてください。
docker compose は実行中ディレクトリの Compose ファイルを参照するため、以降はこのディレクトリで実行します。
別ディレクトリで実行すると no configuration file provided になります。
コンテナを起動し、状態を確認します。
docker compose up -d
docker compose ps
docker compose exec app php -v
docker compose exec app composer --version
続いて、最小の composer.json を作成します。
空ディレクトリでも導入手順を安定化し、name などの初期値を明示するためです。
~/projects/php-formatter-demo/composer.json
{
"name": "example/php-formatter-demo",
"type": "project",
"require": {},
"require-dev": {}
}
ここまでで docker compose exec app ... が通らない場合は、次の章に進まず 7 章のトラブルシュートを先に確認してください。
3. php-cs-fixer を導入する
2章で作成した app コンテナ内で php-cs-fixer を dev 依存として追加します。
本番イメージに php-cs-fixer は不要なため、--dev で追加します。
docker compose exec app composer require --dev friendsofphp/php-cs-fixer
docker compose exec app vendor/bin/php-cs-fixer --version
確認ポイント:
composer.jsonのrequire-devにfriendsofphp/php-cs-fixerが追加されるcomposer.lockが更新されるvendor/bin/php-cs-fixer --versionが成功する
4. .php-cs-fixer.dist.php を最小構成で作る
2章で code . を実行していれば、そのまま VS Code で作業を続けられます。
src を先に作成しておきます(5章でこのディレクトリ配下を整形対象として使用します)。
mkdir -p src
.php-cs-fixer.dist.php をプロジェクト直下に作成します。
~/projects/php-formatter-demo/.php-cs-fixer.dist.php
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/src')
->name('*.php')
->ignoreDotFiles(true)
->ignoreVCS(true);
return (new PhpCsFixer\Config())
->setRiskyAllowed(false)
->setRules([
'@PSR12' => true,
'array_syntax' => ['syntax' => 'short'],
'single_quote' => true,
'no_trailing_whitespace' => true,
])
->setFinder($finder);
allow-risky は本記事では扱わないため、setRiskyAllowed(false) を明示しています。
デフォルト値も false ですが、risky ルールを使わない設定だと見て分かるように、このまま書いています。
.editorconfig をプロジェクト直下に作成します。
~/projects/php-formatter-demo/.editorconfig
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
役割の違い:
.editorconfig: 改行コード、インデントなどの基本規約php-cs-fixer: PHP の構文スタイル(配列記法、引用符、空白など)
5. --dry-run --diff で確認してから fix を実行する
まず、整形対象のサンプルを用意します。
ここでは、WSL 側プロジェクトディレクトリが app コンテナへバインドマウントされている前提で進めます(ホスト側で作成したファイルをコンテナ内の php-cs-fixer から参照します)。
~/projects/php-formatter-demo/src/Sample.php
<?php
class Sample{
public function run( ) : array {
return array( "status" => "ok" );
}
}
--dry-run --diff で差分を確認:
設定ファイルでは Finder で対象範囲を定義できます。
ただし fix コマンドにパス引数を渡した場合は、そのパスが優先されます。
本記事では対象を明確にするため、src を引数で指定します。
docker compose exec app vendor/bin/php-cs-fixer fix --dry-run --diff src
差分出力の例:
--- src/Sample.php
+++ src/Sample.php
@@ -1,6 +1,9 @@
<?php
-class Sample{
-public function run( ) : array {
-return array( "status" => "ok" );
-}
-}
+class Sample
+{
+ public function run(): array
+ {
+ return ['status' => 'ok'];
+ }
+}
php-cs-fixer / PHP のバージョン差やルール構成により、表示される差分行が追加される場合があります。
差分ヘッダの形式(例: --- Original / +++ New)もバージョンにより異なる場合があります。
問題なければ fix を実行:
docker compose exec app vendor/bin/php-cs-fixer fix src
最後にもう一度 --dry-run --diff を実行し、差分が出ないことを確認します。
6. 任意: composer scripts で実行を簡略化する
毎回長いコマンドを打ちたくない場合は、composer.json の scripts セクションに任意で追記します(既存キーは残したまま追加してください)。
{
"scripts": {
"format:check": "php-cs-fixer fix --dry-run --diff src",
"format:fix": "php-cs-fixer fix src"
}
}
Composer scripts 実行時は vendor/bin が PATH に追加されるため、vendor/bin/php-cs-fixer のプレフィックスを省略できます。
実行例:
docker compose exec app composer format:check
docker compose exec app composer format:fix
この節はあくまで任意です。
保存時自動整形(editor.formatOnSave)の強制は、本記事では扱いません。
日常作業の時短として、VS Code の PHP 整形拡張を使う運用は可能です。
ただし、チームで差分をそろえるために、最終確認は docker compose exec app composer format:check(または docker compose exec app vendor/bin/php-cs-fixer fix --dry-run --diff src)で統一してください。
7. よくある詰まりと対処
| 症状 | 主な原因 | 確認 | 対処 |
|---|---|---|---|
no configuration file provided | Composeファイルがあるディレクトリで実行していない | pwd と ls -la で compose.yml の存在を確認 | 2章で作成したディレクトリへ cd して再実行 |
service "app" is not running | app コンテナが未起動 | docker compose ps | docker compose up -d を実行してから再試行 |
vendor/bin/php-cs-fixer が見つからない | 導入失敗 / 実行場所違い | docker compose exec app ls -la vendor/bin | 3章の導入コマンドを再実行 |
| コマンドは通るが期待通り整形されない | Finder対象がズレている | .php-cs-fixer.dist.php の ->in(__DIR__ . '/src') を確認 | 対象ディレクトリを実プロジェクトに合わせる |
| 実行結果が環境ごとに違う | 別バージョン(php-cs-fixer / PHP)で実行している | docker compose exec app php -v と docker compose exec app vendor/bin/php-cs-fixer --version を確認 | docker compose exec app ... に統一し、コンテナ内バージョンで再確認 |
| 差分が多すぎる | いきなり fix を実行 | --dry-run --diff で事前確認 | 一度に適用せず、対象範囲を絞って実行 |
トラブル時の再確認コマンド:
docker compose exec app pwd
docker compose exec app php -v
docker compose exec app vendor/bin/php-cs-fixer --version
docker compose exec app vendor/bin/php-cs-fixer fix --dry-run --diff src
8. まとめと次の一歩
本記事で、次の状態がそろいました。
appコンテナ内でphp-cs-fixerを再現可能に実行できる--dry-run --diff->fixの安全な手順で整形できる.editorconfigとphp-cs-fixerの責務分離を維持できる
次の一歩:
- CI で
format:checkを実行して整形崩れを検出する - PHPCS/PHPCBF との住み分けを定義する
- チームの運用合意後に保存時自動整形を検討する