こんにちは!
スマレジ・テックファームのWebエンジニアやまてと申します。
はじめに
今回は「CLIで操作するブラックジャックゲームをPHPで作ってみる」の 2 回目として、使用する「開発環境構築」について投稿したいと思います。
この課題は、『独学エンジニア』というWeb開発(主にサーバーサイド)の動画学習教材の課題です。
前回までの投稿
PC環境
- macOS Big Sur バージョン: 11.6
- Visual Studio Code バージョン: 1.70.2
- Docker バージョン: 20.10.14
INDEX
1. 開発環境の用意
まずは、開発環境を用意することから始めました。
「用意する」とは言え、今回は一から構築したわけではなく、講師の山浦さんが講義用に作成された Docker 環境(php 8 系, apache )に、課題を進めていく中で静的解析ツールなどのライブラリを追加していったあとの環境を、そのまま使用しています。
以降、主要なツール等を確認していきます。
2. Docker
docker-compose.yml
version: "3" services: app: build: context: . dockerfile: docker/app/Dockerfile volumes: - ./src:/var/www/html ports: - "50080:80"
- Dockerコンテナは、PHP を動作させる app コンテナ一つのみです。
- src ディレクトリ以下(ホスト側)を、 var/www/html ディレクトリ以下(Dockerコンテナ側)にマウントします。
app コンテナの Dockerfile の内容は以下のとおりです。
docker/app/Dockerfile
FROM php:8-apache WORKDIR /var/www/html # PHP で必要なライブラリをインストール RUN apt-get update \ && apt-get install -y libonig-dev libzip-dev unzip \ && docker-php-ext-install mbstring zip bcmath \ && pecl install xdebug \ && docker-php-ext-enable xdebug # composer のインストール COPY --from=composer:2 /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 # ファイルのコピー COPY ./src /var/www/html COPY ./docker/app/php.ini /usr/local/etc/php/php.ini COPY ./docker/app/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
- Docker イメージについては、公式イメージから
php:apache
の 8 系を指定して、使用しています(PHP バージョン: 8.1.7)。
- コンテナ内で実行するコマンドを定義する
RUN
、 ホストのファイルやディレクトリを Docker イメージにコピーするCOPY
で、以下を実行する記述をしています。
参考:composer.json
{ "name": "root/html", "require-dev": { "squizlabs/php_codesniffer": "3.*", "phpmd/phpmd": "@stable", "phpunit/phpunit": "^9.5", "phpstan/phpstan": "^0.12.81", "barryvdh/laravel-ide-helper": "^2.9" }, "scripts": { "phpcs": "./vendor/bin/phpcs --standard=phpcs.xml", "phpmd": "./vendor/bin/phpmd . text rulesets.xml --suffixes php --exclude node_modules,resources,storage,vendor", "phpunit": "./vendor/bin/phpunit", "phpstan": "vendor/bin/phpstan analyse -c phpstan.neon" } }
3. Xdebug
PHP のデバッグツールである Xdebug で、必要に応じて、ステップ実行してデバッグしながらコーディングします。
Xdebug を利用する方法としては、 Visual Studio Code の拡張機能として導入した Remote Development を利用して、 Docker コンテナ内でデバッグ機能を設定する方法で使用します。
画像引用元:
4. PHPUnit
単体テストには、 テストフレームワーク PHPUnitを導入しています。
https://phpunit.readthedocs.io/ja/latest/#phpunit.readthedocs.io
- Composer を使ってインストールして、PHPUnit の設定ファイル phpunit.xml に設定を書き込んでいます。
- composer.json にコマンドを登録して、下記コマンドで、テストが実行されるようにしています。
composer phpunit
5. 静的解析ツール
静的解析ツールは、講義の中で学んできた、以下の3つを導入しています。
作業の節目で静的解析ツールを利用してチェックしながら実装を進めます。
5-1. PHP_CodeSniffer
コーディング規約に則って実装できているかをチェックしてくれます。
- Composer を使ってインストールして、PHP_CodeSniffer の設定ファイル phpcs.xml に設定を書き込んでいます。
- composer.json にコマンドを登録して、下記をコマンド実行すれば、テストするようにしています
composer phpcs
例えば、実行時このようなことをチェックしてくれます。
root@9444efa94780:/var/www/html# composer phpcs > ./vendor/bin/phpcs --standard=phpcs.xml FILE: /var/www/html/lib/Deck.php -------------------------------------------------------------------------------------------------------------------------------- FOUND 1 ERROR AFFECTING 1 LINE -------------------------------------------------------------------------------------------------------------------------------- 41 | ERROR | [x] Parentheses must be used when instantiating a new class | | (PSR12.Classes.ClassInstantiation.MissingParentheses) -------------------------------------------------------------------------------------------------------------------------------- PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY --------------------------------------------------------------------------------------------------------------------------------
「新しいクラスをインスタンス化する際には、括弧を使用する必要があります」
という指摘があり、下記のように修正すると解消されます。
- $card = new Card; + $card = new Card();
このような、コーディング規約(PSR12)に則っていない箇所を教えてくれます。
5-2. PHPMD
PHPMDは、考えられるバグや最適でないコード、複雑なコード、未使用のパラメーター、メソッド、プロパティなど、問題のありそうなコードを検知して教えてくれるツールで、良いコードに近づけてくれます。
- Composer を使ってインストールして、PHPMD の設定ファイル phpmd.xml に設定を書き込んでいます。
- composer.json にコマンドを登録して、下記をコマンド実行すれば、テストするようにしています
composer phpmd
例えば、実行時このようなことをチェックしてくれます。
root@9444efa94780:/var/www/html# composer phpmd > ./vendor/bin/phpmd . text rulesets.xml --suffixes php --exclude node_modules,resources,storage,vendor /var/www/html/lib/Game.php:13 ExcessiveClassComplexity The class Game has an overall complexity of 55 which is very high. The configured complexity threshold is 50.
「Gameクラスの全体的な複雑度は55で、非常に高いです。設定されている複雑さの閾値は50です。」
「複雑度」とは if
, while
, for
などを足し合わせて算出されるようで、複雑さの閾値を超えるとチェックに引っ掛かります。
5-3. PHPStan
こちらもバグになりそうなところを見つけてくれるツールです。
- Composer を使ってインストールして、PHPStan の設定ファイル phpstan.neon に設定を書き込んでいます。
- composer.json にコマンドを登録して、下記をコマンド実行すれば、テストするようにしています
composer phpstan
例えば、実行時このようなことをチェックしてくれます。
------ -------------------------------------------------------------------------------------------------------------------- Line lib/Player.php ------ -------------------------------------------------------------------------------------------------------------------- 96 Variable $message might not be defined. 117 Method Blackjack\Player::addACardToHand() has parameter $card with no value type specified in iterable type array. 💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type ------ --------------------------------------------------------------------------------------------------------------------
lib/Player.php ファイルの 96 行目について、
「変数 $message が定義されていない可能性があります。」
という指摘があり、下記を追記して定義してから使うと解消されます。
+ $message = '';
続いて、117 行目については、
「メソッド BlackjackPlayer::addACardToHand() は、反復可能な型配列で指定された値型を持たないパラメータ $card を持ちます。」
という指摘があり、下記を修正すると解消されます。
/** * 1枚カードを手札に加える * - * @param array $card + * @param array<array<string,string|int>> $card * @return void */ public function addACardToHand(array $card): void
このように、 PHPDoc の記載内容についてチェックしてくれることもあります。
おわりに
今回は、使用する「開発環境構築」について確認しました。次回は UML について投稿します。
今回の記事は以上です!ありがとうございました。
投稿したQiita記事を読んでもらって、人に何か共有したり、詳しい人にはさらに教えてもらえたり、良い影響を与え合える喜びがある。公務員の頃はそういった交流はできなかったから、自分にとってはIT業界に来ることで得た、楽しみの一つと感じる。
— やまて|Webエンジニア2年目 (@r_yamate) 2022年8月17日
最近は Qiita の投稿を読んで、参考になった!という声をいただけることが増えて、嬉しい限りです。