PHPのフレームワークLaravelを使って、EloquentのModelクラスからMySQLのsakila DBにアクセスするサンプルの作成手順を説明しています。DBはDockerのdocker-composeで作成します。
本ドキュメントは、MySQLやプログラム、初歩的なdockerの知識がある人向けです。
最小限のコマンドと実行結果のみ抜粋して書いているので、手順だけ知りたい人におすすめの記事です。
DBの準備
MySQLのDocker設定
MySQLのDBを用意するために、以下の内容でdocker-compose.ymlを作成します。今回の例ではMySQLのDBは公式コンテナを利用し、バージョンは8.0を使用しています。
後で作成するdocker/db/sqlディレクトリを/docker-entrypoint-initdb.dにマウントしています。mysqlの公式Dockerコンテナは起動時に/docker-entrypoint-initdb.dディレクトリにある*.sqlを自動で実行してくれるため、初期DBを自動作成する準備を行っています。
version: '3'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: pass
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/db/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
docker-compose.ymlに、以下の内容も追加しておくとPHPMyAdminも使えます。
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOSTS=db
- PMA_USER=root
- PMA_PASSWORD=pass
ports:
- 8080:80
sakilaDBのダウンロード
下記のコマンドでsakila DBのテーブル定義、サンプルデータのinsert文を取得します。
$ wget 'http://downloads.mysql.com/docs/sakila-db.zip'
$ unzip sakila-db.zip
取得したら、docker/db/sqlにコピーします。これで、dockerの起動時にこのSQLが実行されます。データ登録よりDB作成の方を先に実行させるため、ファイル名の先頭に01, 02をつけます。
$ mkdir -p docker/db/sql
$ mv sakila-db/sakila-schema.sql docker/db/sql/01-sakila-schema.sql
$ mv sakila-db/sakila-data.sql docker/db/sql/02-sakila-data.sql
# 不要なファイルを削除
$ rm -rf ./sakila-db ./sakila-db.zip
dockerのコンテナ実行
下記のコマンドでコンテナを起動します。
$ docker-compose up -d
コマンド実行後ちょっとまって(1分ぐらい)、ブラウザからhttp://localhost:8080/
にアクセスすると、phpMyAdminが起動できます。
左のメニューにある、sakila > Tables > TABLE_NAMEをクリックしテーブルのデータが表示されることを確認します。
Laravelの準備
laravelコマンドでアプリケーションの雛形をappディレクトリに作ります。(laravelコマンドのインストール方法は公式サイトに記載があります)
$ laravel new app
バージョンを確認しておきます。
$ cd app
$ php artisan --version
Laravel Framework 8.7.1
.envファイルにあるDB接続情報を編集します。
$ vi .env
docker-composeに書いた内容を反映させるため、以下の内容に書き換えます。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sakila
DB_USERNAME=root
DB_PASSWORD=pass
tinkerコマンドでDBに接続できることを確認します。php artisan tinker
で起動し、DB::select("show tables");
を実行するとテーブルの一覧が表示されます
$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.9 — cli) by Justin Hileman
>>> DB::select("show tables");
=> [
{#3235
+"Tables_in_sakila": "actor",
...
+"Tables_in_sakila": "store",
},
]
モデルクラスを作ります。今回は、sakila DBのlanguageテーブルに接続することを想定しています。
$ php artisan make:model Language
Laravel 8.*の場合このコマンドでapp/Models/Language.phpファイルが作成されます。内容を確認しておきます。
$ cat app/Models/Language.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Language extends Model
{
use HasFactory;
}
sakila DBのLanguage クラスの中身を変更します。
vi app/Models/Language.php
sakilaのDBはLaravelが想定するテーブル名の命名規則に沿っていないので、3つほど定義が必要になっています。
...
class Language extends Model
{
protected $table = 'language';
protected $primaryKey = 'language_id';
public $timestamps = false;
}
作成したModelクラスをtinker経由で動作確認します。App\Models\Language::get();
でテーブルの内容が表示されれば成功です。
$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.9 — cli) by Justin Hileman
>>> App\Models\Language::get();
=> Illuminate\Database\Eloquent\Collection {#3253
all: [
App\Models\Language {#3254
language_id: 1,
name: "English",
last_update: "2006-02-15 05:02:19",
},
App\Models\Language {#3255
language_id: 2,
name: "Italian",
last_update: "2006-02-15 05:02:19",
},
App\Models\Language {#3256
language_id: 3,
name: "Japanese",
last_update: "2006-02-15 05:02:19",
},
App\Models\Language {#3257
language_id: 4,
name: "Mandarin",
last_update: "2006-02-15 05:02:19",
},
App\Models\Language {#3258
language_id: 5,
name: "French",
last_update: "2006-02-15 05:02:19",
},
App\Models\Language {#3259
language_id: 6,
name: "German",
last_update: "2006-02-15 05:02:19",
},
],
}
以上で作業は完了です。
後片付け
作成したdockerのイメージが不要な場合、下記のコマンドで、コンテナの停止/コンテナイメージの削除/ボリュームの削除(今回はありませんが)を全部行えます。
$ docker-compose down --rmi all --volumes
この後に、再度docker-compose up -d
を実行すると、イメージの再ダウンロードがからやり直せます。テストで作業していてコンテナの状態がよくわからなくなったときは、この手順で全リセットできるので便利です。