『独習PHP第4版』の環境構築はXAMPPですが、既にDockerをインストールしていたため。これで一冊最後まで学習ができたので記録。
目次
1.先にまとめ
2.起動したら必ずやること
3.dockerのため本書と違うところ
1. 先にまとめ
【使用環境】
・OS : Windows10
・Docker Desktop : 4.16.2
・Docker Engine: 20.10.22
・WSL2(Ubuntu) : Ubuntu 20.04.5 LTS (Focal Fossa)
・VSCode : 1.75.0
全体図
selfphp
|---mariadb
| |___data //空ディレクトリ
| |___Dockerfile
|---php
| |___docker-php-ext-xdebug.ini
| |___Dockerfile
| |___myphp.ini
|---web //ドキュメントルート(後述)。PHPのコードはこの下に。
| |___parts //呼び出して使う関数はここに保管
| | |___DbManager.php //PHPとデータベースを接続するためのファイル
| |___index.php //好きに作業する
|___docker-compose.yml
MariaDB(MySQL)
FROM mariadb:10.7.7-focal
EXPOSE 3306
MySQLの場合はFROM mysql:8.0-debian
とした。
PHP
[xdebug]
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
;デバッグを実行すると、PHPコンテナ内の/tmp/xdebug.logにログが出力される。
xdebug.log=/tmp/xdebug.log
xdebug.client_port=9003
FROM php:8.2-rc-apache
# ① 「user」という名の一般ユーザーを作成。
ARG USERNAME=user
ARG GROUPNAME=user
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID $GROUPNAME && \
useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
# ②「libzip-dev」「unzip」「pdo_mysql」「zip」「xdebug」「mhsendmail」をインストール&有効化
RUN apt-get update \
&& apt-get install -y --no-install-recommends libzip-dev unzip \
&& docker-php-ext-install pdo_mysql zip \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& curl -sSL https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 -o mhsendmail \
&& chmod +x mhsendmail \
&& mv mhsendmail /usr/local/bin/mhsendmail
# ③ ComposerをPHPコンテナ内に取り入れる
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer
# ④ 自作の設定ファイル「myphp.ini」「docker-php-ext-xdebug.ini」をPHPコンテナに適用させる
COPY myphp.ini /usr/local/etc/php/conf.d
COPY docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
# ⑤ PHPコンテナ内に入った時のカレントディレクトリを指定
WORKDIR /var/www/html
EXPOSE 80
【参考】
①https://qiita.com/Spritaro/items/602118d946a4383bd2bb
③Composer公式ドキュメント「Docker Image」の項にて。イメージはdockerが提供している「composer」でなく、Composer公式の「composer/composer」を使用。『dockerのイメージは、公式が直接公開したものではないので、最新版を受け取るのに数日遅れる。バイナリのみの同等のものがない』らしい。
[Core]
sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025"
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.language = "Japanese"
[Session]
;session使用時、実データがPHPコンテナ内の/tmp下に保存される。
session.save_path = "/tmp"
;以下は、本書で紹介されている「推奨値」を設定。
session.cookie_httponly = "On"
session.cookie_samesite = "Lax"
session.sid_length = "48"
session.sid_bites_per_character = "6"
session.use_strict_mode = "On"
web
<?php
$dsn = 'mysql:dbname=selfphp; host=db; charset=utf8';
$usr = 'root';
$passwd = 'myrootpassword';
try {
$db = new PDO($dsn, $usr, $passwd);
print '接続に成功しました。';
}catch (PDOException $e) {
die("接続エラー:{$e->getMessage()}");
} finally {
$db = null;
}
このコードは『独習PHP第4版』から拝借。
docker-compose.yml
version: '3'
services:
app:
build:
context: ./php
dockerfile: Dockerfile
volumes:
- type: bind
source: "./web"
target: "/var/www/html"
ports:
- "80:80"
depends_on:
- db
db:
build:
context: ./mariadb
dockerfile: Dockerfile
volumes:
- type: bind
source: "./mariadb/data"
target: "/var/lib/mysql"
ports:
- "3306:3306"
environment:
# MySQLのイメージを使用するなら、環境変数は「MYSQL_ROOT_PASSWORD」に。
- MARIADB_ROOT_PASSWORD=myrootpassword
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025"
- 通常の起動・停止
docker-compose up -d
で起動、docker-compose down
で停止。この起動はキャッシュを使うので、もしファイルを修正したら、起動時はdocker-compose up -d --build
でビルドから始める。 - コンテナ名
docker-compose
コマンドで起動したら、コンテナ名は「作業中のディレクトリ名-コンテナ名-1」となる。例えばPHPコンテナ名は「selfphp-app-1」。(docker ps
で確認可) - ウェブ上で表示できるか確認する
・index.php
にアクセスするには「http://localhost:80/index.php
」。
・web
と/var/www/html
のマウントによって、ウェブで公開する部分(ドキュメントルート)を設定している。(PHPイメージのドキュメント「php:<version>-apache」の項にて)
・ ブラウザ上でのパスを確認したいなら、print __FILE__;
で出力するとよい。 -
mariadb/data
と/var/lib/mysql
のマウント
データを保持するため。MariaDBイメージのドキュメントより「Where to Store Data」の項。コンテナを停止する度にコンテナは削除される。データベースやテーブルなどのデータは、MariaDBコンテナ内で作成するのでデータも都度消えてしまう。マウントすることでデータを常に保持できる。 - コンテナ内に入る。
docker exec -it コンテナ名 /bin/bash
- PHPコンテナ内での作業
・ Composerを使ってパッケージをインストールする時。
・ sessionが正しく機能しているかチェックする時(コンテナ内の/tmp
をls
で確認)。
・ デバッグのログを見たい時(コンテナ内の/tmp/xdebug.log
に出力される)。 - MariaDBコンテナ内での作業
・ データベースやテーブルを作成したり、SQLを実行する時。
・PHPとデータベースを接続するためにIPアドレスを確認する時。
2. 起動したら必ずやること
①launch.jsonに"pathMappings"を追記する。
(②zend_extension
の値を書き直す。)
③PHPとデータベースを接続する時、DockerではhostのIPアドレスを毎回確認する。
④Composerを利用する時は、PHPコンテナにユーザーを指定して入る。
簡単です!
①launch.jsonに"pathMappings"を追記する。
これはデバッグを実行するために必要な作業。
事前に、VSCodeの拡張機能をインストールする所から「PHP Debug」を検索し、インストールしておく。
(1)初めての方は、虫マーク→「create a launch.json file.」→「PHP」を選択。selfphp
下に.vscode/launch.json
ファイルが自動作成される。
(2)launch.json
ファイルを見て、portが「9003」であることを確認。
そしてこの"port: 9003"
の下に以下のコードを追記。
"pathMappings": {
"/var/www/html":"${workspaceFolder}/web"
}
- 左側(
/var/www/html
)はPHPコンテナのドキュメントルートのパス。 - 右側(
${workspaceFolder}/web
)は作業中のドキュメントルートのパス。
docker-compose.yml
ファイルからも分かるように、/var/www/html
とマウントしている部分。${workspaceFolder}
は今、VSCodeで開いているディレクトリ(selfphpディレクトリ)。
▼【完成したlaunch.json
】
(3)正しくデバッグできるか確認する。
簡単にチェック用のindex.phpを作成する。このコードは『独習PHP第4版』から拝借。
<?php
$msg = 'こんにちは、世界!';
print $msg;
デバッグしたいファイルindex.php
を開いた状態で虫マーク→「Listen for Xdebug」であることを確認して横の三角をクリック(デバッグ開始)。
↓このマークが出る。ちなみに終了は一番右の四角をクリック。
index.php
のコード左側をクリックしてブレークポイントを設置。ブレークポイントの行は実行せず、一時停止する。
ブラウザからhttp://localhost:80/index.php
でindex.php
にアクセス→VSCodeに戻る。下のようにブレークポイントで止まっていればOK。
ブレークポイントの行は実行されずに止まるので、$msg
の値はまだ初期化されていないと出る。これでデバッグは問題なく使用できる。
【参考】
・https://zenn.dev/ikeo/articles/244d6a8042bcd8c55fe9
・https://qiita.com/gigosa/items/90431be7a6a79db78480
(②zend_extensionのパスを書き換える)
- Xdebug公式のドキュメント「Configure PHP」の項にて、もしXdenugが表示されなかったり、ファイルが見つからないと出たらXdebugのファイルパスを明示的に設定する。
- PHPコンテナ内に入り、
cd
で/usr/local/lib/php/extensions
あたりまで行く。ls
とcd
で追ってパスを確認する。
[xdebug]
zend_extension=xdebug
↓
[xdebug]
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20210903/xdebug.so
ファイルを変更したので、Dockerを停止→docker-compose up -d --build
で起動する。
③PHPとデータベースを接続する時、DockerではhostのIPアドレスを毎回確認する。
こんなことしなくてもよいみたいです。
hostの部分は、MariaDbコンテナの「IPアドレス」ではなく「コンテナ名」を書けばOK。コンテナ名は、docker-compose.yml
ファイルのservices
にある。ここでMariaDbコンテナをdb
と名付けた。正式名selfphp-db-1
を使ってもどちらでもよい。
【修正前】host=172.19.0.2
【修正後】host=db
<?php
$dsn = 'mysql:dbname=selfphp; host=db; charset=utf8';
$usr = 'root';
$passwd = 'myrootpassword';
try {
$db = new PDO($dsn, $usr, $passwd);
print '接続に成功しました。';
}catch (PDOException $e) {
die("接続エラー:{$e->getMessage()}");
} finally {
$db = null;
}
hostにはMariaDbコンテナのIPアドレスを書く。起動すると変わることがあるので毎回確認する。
(1)起動後、docker exec -it selfphp-db-1 /bin/bashでMariaDBコンテナに入る。
(2)cat /etc/hostsで確認。
127.0.0.1 localhost
~省略~
172.23.0.2 12ab34cd56ef ←こっち。つまり172.23.0.2をhostに書く。
一番下、MariaDBのコンテナIDと共に表示されている方のIPアドレス。同じものをhostに書く。
-
mysql:dbname=selfphp
の「selfphp」とは、MariaDBで作成したデータベース名。Dockerの場合、MariaDBコンテナに入る→mariadb -p
(MySQLの場合はmysql -p
)→パスワード入力(docker-compose.yml
のMARIADB_ROOT_PASSWORD
で設定済)でMariaDBを起動。CREATE DATABASE selfphp;
でデータベースを作成。テーブルも作っておく。 -
$passwd
は、先ほど入力したパスワード。
(3)http://localhost:80/parts/DbManager.php
でファイルにアクセスし、「接続に成功しました。」が出ればOK。
④Composerを利用する時は、PHPコンテナにユーザーを指定して入る。
Composerを利用する時は、docker exec -it -u user selfphp-app-1 /bin/bash
でPHPコンテナに入ること。
- コンテナに入る時は、
-u(--user) user
でユーザーを指定しないとrootユーザーで入ることになる。 そのため、コンテナ内で作業して作られたファイルなどが全てroot権限で、後で全く編集できなくなり困った。 - そもそもComposerのドキュメントにrootで実行するなと書かれている。なので、PHPのDockerfileで「user」という名のユーザーを作成した。これがないとrootでしか入れない。
- ちなみにroot権限で作業してしまい、ファイルが編集できなくて詰んだ時は…userに権限を変更する。以下のコマンドをそのまま実行。
(1)chown -R user:user ./
カレントディレクトリ下の使用者権限を全て変更。user:user
の部分は、ユーザー名:グループ名。
(2)find . -type f -print | xargs chmod 644
カレントディレクトリ下の、ファイルの実行権限を全て644に変更。
(3)find . -type d -print | xargs chmod 755
カレントディレクトリ下の、ディレクトリの実行権限を全て755に変更。
【参考】https://cpoint-lab.co.jp/article/202206/22876/
3. dockerのため本書と違うところ
①mb_send_mail()を使ってメール送信
※ 本書では、XAMPPに元から入っている「sendmail」を使って実際にメールを送信しますが、僕の知識不足のため、導入が簡単な「MailHog」と「mhsendmail」を使いました。学習に支障はありませんが、本書通りにできたら追記します(検証中)。
※ もし「sendmail」を使いたい方は、PHPコンテナにインストールする必要があるので、PHPのDockerfileに「sendmail」を追記してください。
~ 省略 ~
apt-get install -y --no-install-recommends libzip-dev unzip sendmail \
MailHogの使い方は簡単
- 「MailHog」は、PHPのアプリでメール機能をつける時、mb_send_mail関数を使う時などで、実際にメールが届いた側としてメールの状況を確認できる(本文の表示崩れなど)。
- 実際の宛先には送信せず、「MailHog」に送信する。「MailHog」にメールを送信するために「mhsendmail」が必要なので、両方インストール。「sendmail」でも可能らしいが未検証。
(1)http://localhost:8025
で「MailHog」を開く。ここで受信したメール、メールヘッダーが確認できる。
(2)mb_send_mail関数で、メールを送信するファイルを作成(本書に手順があるので省略)
本書の書き方と変えた所
- mb_send_mail関数のメールヘッダー(
$headers
)は配列で渡した。PHP7.2以降から可能。これはメールヘッダーインジェクションの防止になる。 - メールヘッダー(
$headers
)の配列に'Content-Type'=>'text/plain; charset=UTF-8', 'Content-Transfer-Encoding'=>'8bit'
を追記。mb_send_mail関数で送信した文字コードは日本語(ISO-2022-JP)だったが、「MailHog」では文字化けするので、UTF-8を指定した。
【参考】https://teratail.com/questions/318732
(3)そのファイルにアクセスする。または、PHPコンテナ内に入ってphp ファイル名
で実行する。→(1)「MailHog」を見る。
- Fromヘッダーの値の書き方
①差出人の名前で表示したい・・・差出人名<from@example.com>
②メールアドレスで表示する・・・from@example.com
こんな感じで届きます↓
②PHPDocの使い方
- PHPDocumentor(以下PHPDoc)は、コードから自動で必要な情報を取り出し、仕様書として整形してくれる。
- 整形したいファイルにあらかじめドキュメンテーションコメントを書く必要があるが、書き方は本書やドキュメントなどにあるので省略。
インストールの方法は3つ。
- dockerイメージを使う。→僕はDockerなのでこの方法
- Phiveを使い、依存関係としてインストールする。
- PHARファイル(.phar)をダウンロードし、好みの場所に配置する。→本書はこの方法
※Composerを使ってもインストールできるが非推奨。PHPDoc側とこちら側の依存関係でコンフリクトが起こる可能性がある。
PHPDocのdockerイメージを使う
(1)このツールを使用すると、いくつかディレクトリが作成されるので、1つにまとまっていた方が綺麗だなー…と思い、web
ディレクトリにphpdoc
ディレクトリを作った( (3)の図)。ここをカレントディレクトリとして作業する。
(2)カレントディレクトリで以下のコマンドを実行。エイリアス(別名)を作成。
alias phpdoc="docker run --rm -v $(pwd):/data phpdoc/phpdoc:3"
- 自作したコマンド「
phpdoc
」だけでPHPDocコンテナの起動/マウント/削除を行う。「=」の前後にスペースを入れないこと! - このエイリアスはその場限りで、エディタを閉じると設定が消えるので注意。
alias
と打つと、設定したエイリアス一覧を確認できる。すると、$(pwd)
の部分が絶対パスに置き換わっている。
(3)カレントディレクトリに、「doc」「out」というディレクトリを作成する。
「doc」には、ドキュメンテーションコメントを書いたファイルを置こう。
selfphp
:
|___web
| |___phpdoc(カレントディレクトリ)
| |___doc //ドキュメント化したいファイルはここに置く。
| | |___ファイル1
| | |___ファイル2
| |___out //空ディレクトリ。作成されたドキュメントが自動でここに入る
:
(4)カレントディレクトリでphpdoc -d doc -t -out
を実行する。
-
-d
は、ドキュメント化したいファイルが入っているディレクトリ。 -
-f
でファイルを指定することもできる。 -
-t
は、生成されたドキュメントを入れる場所(ディレクトリ)。Target Folderと呼ぶ。
【参考】
・https://docs.phpdoc.org/3.0/guide/guides/running-phpdocumentor.html
(5)「out」下に作成された、index.html
にアクセスする。すると自分で作ったファイルがドキュメント化されている。
以上となります。最後まで読んでいただき、ありがとうございました。