PHPフレームワーク、Laravel5.5で簡単なシステムを作ってみます。CRUDを一回り作ってみるチュートリアルです。

前提

PHP、Laravelはすでにインストール済みでblogというプロジェクトが生成されている状態から始めます。まだインストールが済んでいない場合は、「PHPフレームワークLaravel 5.5をインストールする」を参考に作業を進めておいてください。

データベースを作成する

今回作成するblogシステム用のデータベースを作成します。データベース名をblogとしてデータベースを作成してください。また、データベースにアクセスできるユーザも合わせて作成します。
PHPフレームワークLaravel 5.5をインストールする」の手順でインストールした場合は、phpMyAdminを使ってデータベースを作成するのが簡単だと思います。
XAMPP Control PanelのMySQLのAdminボタンをクリックするとphpMyAdminを起動できます。
phpMyAdminの起動

データベース接続の設定をする

Laravelにデータベースの設定をします。
データベースの設定はconfig\database.phpにあります。

28行目のdatabaseでデータベース名、
29行目のusernameでデータベースに接続するユーザ名、
30行目のpasswordでデータベースに接続するユーザ名のパスワード
を設定します。
環境によってはその他の設定値も変更する必要があるかもしれません。
ここで少し注意が必要なのが、env('DB_DATABASE', 'forge')の記述です。env関数は.envファイルの設定値を読み込む関数で、第1引数に指定された設定値を読み込みます。設定値が未設定の場合には第2引数で指定された値が設定値となります。したがって、'database' => env('DB_DATABASE', 'hogehoge'),と変更しても.envでDB_DATABASEが設定されている場合は.envの設定の方が優先され、データベース名がhogehogeに変更されません。'database' => 'hogehoge',と変更するか、.env側を変更しましょう。ここでは.envを変更することにします。

テーブルを作成する

テーブルを作成するにはデータベースを作成したのと同様にphpMyAdminなどで直接作成しても構いませんが、Laravelにはテーブルを編集するためのマイグレーションと呼ばれる機能があります。ここではこの機能を使ってテーブルを作成します。

マイグレーションを生成する

make:migration Artisanコマンドを使ってマイグレーションを生成します。ArtisanコマンドはLaravelのコマンドでLaravelプロジェクトの直下でphp artisan make:migration create_articles_tableコマンドを実行してください。

マイグレーションファイルを編集する

マイグレーションを生成するとdatabase\migrations\xxxx_xx_xx_xxxxxx_create_articles_table.phpファイルが作成されます。xxの部分は日時が入ります。このファイルを以下のように編集します。

元の記述から変更したのは18行目と19行目だけです。16~21行目でarticlesテーブルを作成しています。テーブルのフィールドの設定が17~20行目です。17行目は主キーのidフィールド、18行目はブログタイトルのtitleフィールド、19行目はブログ本文のbodyフィールド、20行目はcreated_atフィールド・updated_atフィールドを設定しています。
incrementsやtextメソッドは作成されるフィールドの型を指定しています。指定できる型は公式ドキュメントを参考にすると良いでしょう。

不要なマイグレーションファイルを削除する

編集したマイグレーションファイルと同じディレクトリにデフォルトで他に2つのファイルがあります。このファイルは認証機能用のマイグレーションファイルで今回は不要ですので削除しておきます。
database\migrations\2014_10_12_000000_create_users_table.php
database\migrations\2014_10_12_100000_create_password_resets_table.php

マイグレーションを実行する

migrate Artisanコマンドを使用します。php artisan migrateコマンドを実行します。

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytesエラーが出る場合

Laravel5.5で文字セットのデフォルトが変更されたことが原因です。詳細は記事「php artisan migrateでSyntax errorになる」に説明していますので一読ください。

モデルを作成する

articlesテーブルに紐付いたArticleモデルを作成します。make:model Artisanコマンドを使用します。php artisan make:model Articleコマンドを実行してください。

テーブルに初期データを入れる

テーブルには最初何もデータが入っていません。アプリケーションを作成する際に何かデータがあったほうが都合が良いことが多く、Laraveldehaにはテーブルに初期データを入れるためのシーディングと呼ばれる機能があります。ここではこの機能を使ってテーブルの初期データを入れてみます。

シーダを生成する

make:seeder Artisanコマンドを使ってシーダを生成します。php artisan make:seeder ArticlesTableSeederコマンドを実行してください。

シーダーファイルを編集する

マイグレーションを生成するとdatabase\seeds\ArticlesTableSeeder.phpファイルが作成されます。このファイルを以下のように編集します。

5行目で先程作ったArticleモデルをuseします。シーダーが実行されるとrunメソッドが実行されます。16行目から21行目まででarticlesテーブルにデータを挿入しています。

シーダを実行する

db:seed Artisanコマンドを使用します。php artisan db:seed --class=ArticlesTableSeederコマンドを実行します。

データベースの中身を見るとデータが追加されていることがわかります。
seedデータの確認

一覧表示画面(R)を作成する

CRUDのRead、つまり一覧画面を作成します。ブログのタイトルと内容をデータベースから抽出しHTMLに出力します。

コントローラを作成する

まずはコントローラを作成します。Articleコントローラを作成します。
make:controller Artisanコマンドを使用します。php artisan make:controller ArticleControllerコマンドを実行してください。

コントローラを編集する

前の手順でapp\Http\Controllers\ArticleController.phpが作成されますので、これを以下のコードに修正します。

6行目でArticleモデルをuseします。
11行目でarticlesテーブルからデータを抽出します。
12行目でビューを表示します。この時、変数$articlesをビューに渡しています。

ルーティングを設定する

先の手順で作成したコントローラ、メソッドにルーティングを設定します。
ここでは「インストールしたURL/」のアクセスをArticleコントローラのindexメソッドに割り当てます。
routes\web.phpを以下のコードに修正します。

14行目がルーティングの設定になります。それ以外はコメントです。

ビューを作成する

resources\views\article\index.blade.phpファイルを作成します。このとき、articleディレクトリもありませんので作成してください。
コントローラでview('article.index'としているのは、ビューファイルとしてresources\views\article\index.blade.phpファイルを指定していることになります。
このファイルを下記のように作成します。

ビューファイルですので、内容はほぼHTMLです。デザインの簡易化のためにBootstrapを使用しています。
注目すべきは12行目と20行目で、@から始まる文法はLaravelのテンプレートエンジンBladeの記法になります。記号として@を使うくらいでほぼPHPの記法と同じになるので、それほど難しくはないでしょう。
この例では変数$articlesを12行目から20行目まで繰り返しています。繰り返したデータは15行目の{{ $article->title }}で表示しています。繰り返しで変数$articleにデータが1つずつ取り出され、titleプロパティを参照するとデータベースから抽出したtitleフィールドの値を表示できます。{{ }}はBladeの記法でPHPで変数の内容をechoするのと同様の動作をします。(厳密にはXSS対策としてのエスケープも行います)

動作を確認する

http://localhost/にアクセスして動作を確認します。
一覧画面の動作確認
データベースの内容が抽出されて表示されていることがわかります。

新規追加画面(C)を作成する

CRUDのCreate、つまり新規追加画面を作成します。ブログのタイトルと内容をデータベースに挿入します。

コントローラを編集する

app\Http\Controllers\ArticleController.phpに新規追加用のメソッドを追加します。新規追加用のメソッドは新規追加のフォームを表示するメソッド(create)とフォームから送られたデータをデータベースに挿入するメソッド(store)の2つを追加します。

createメソッドは新規追加のフォームを表示しているだけです。
storeメソッドはフォームから送られたデータを変数$requestで受け取り、データベースに書き込んでいます。データベースの操作はEloquent ORMを使用しています。データベースに書き込むためのモデルのインスタンスを生成し、それに書き込むデータをセットしていきます。save()メソッドで実際にデータベースへの書き込みを実行します。

ルーティングを設定する

「インストールしたURL/create」にアクセスした時はをArticleコントローラのcreateメソッドに割り当て、「インストールしたURL/create」にフォームのデータをPOSTした時はArticleコントローラのstoreメソッドに割り当てます。Laravelは同一URLでもmethodによって処理をルーティングで変えることができます。
routes\web.phpを以下のコードに修正します。

ビューを作成する

一覧画面のresources\views\article\index.blade.phpファイルに新規追加用のフォーム画面へのリンクを追加します。

11行目のリンクを追加しているだけです。

新規追加用のフォーム画面resources\views\article\create.blade.phpファイルと、新規追加完了の表示画面resources\views\article\store.blade.phpファイルを作成します。

formタグのaction属性は「/create」を指定します。直接URLにリンクしたのか、フォームからPOSTしたのかは、ルーティングが振り分けてくれます。

動作を確認する

一覧画面から新規追加ボタンをクリックして新規追加画面にリンクします。
新規追加画面
ブログ新規追加画面が表示されます。
必要事項を入力し、「新規追加」ボタンをクリックするとデータベースへの新規追加処理が行われます。
新規追加完了画面
データベースの中身を見ると確かに入力したデータが挿入されているのが確認できます。
新規追加データの確認

更新処理(U)を作成する

CRUDのUPDATE、つまり更新処理(修正)を作成します。すでに入力済みのブログのタイトルと内容を修正します。
一覧画面に修正用のリンクを追加して、このリンクが押されたら修正画面が表示されます。このとき既に入力されているデータが初期状態として入力された状態のフォームを表示します。フォームデータを修正し、修正ボタンをクリックすると修正処理されるようにします。

コントローラを編集する

app\Http\Controllers\ArticleController.phpに修正画面用のメソッドを追加します。修正画面用のメソッドは修正のフォームを表示するメソッド(edit)とフォームから送られたデータでデータベースを更新するメソッド(update)の2つを追加します。

editメソッドは新規追加のときのようにただ単にビューを表示するのではなく、修正すべきデータのIDを引数で渡しています。具体的には変数$idで修正するデータの主キーを受け取ります。この$idでデータベースのデータを抽出し、抽出したデータをビューに渡しています。
データベースの更新処理は新規のArticleインスタンスを作るのではなく、34行目のとおりすでにあるデータを元にArticleインスタンスを生成し、このインスタンスに新たなデータをセットしていくことで更新処理を行うことができます。使用するメソッドは新規追加の時と同様にsaveメソッドです。

ルーティングを設定する

「インストールしたURL/edit/XX」のアクセスをArticleコントローラのeditメソッドに割り当てていますが、割当るURLを’edit/{id}’と記述することで「/edit/XX」にアクセスしたときに引数としてXXを渡すことができます。ここでは修正する対象のデータのIDを渡す設計にしています。
routes\web.phpを以下のコードに修正します。

ビューを作成する

一覧画面のresources\views\article\index.blade.phpファイルに修正用のフォーム画面へのリンクを追加します。

19行目で修正画面へのリンクを追加しています。リンク先が「/edit/id」となるように生成しています。

修正用のフォーム画面resources\views\article\edit.blade.phpファイルと、修正完了の表示画面resources\views\article\update.blade.phpファイルを作成します。

新規追加と異なる点として、初期状態でデータが表示されている必要があります。input要素に関してはvalue属性で初期値を設定し、textarea要素には要素の内容として初期値を設定しています。また、更新の場合は主キーのIDも必要になりますのでIDはhidden要素として保持します。

動作を確認する

一覧画面から修正画面
一覧画面から修正リンクをクリックして修正画面にリンクします。
修正画面
初期データがすでに入力済みの状態になっています。これを一部修正して修正ボタンをクリックします。
修正完了画面
データベースの中身を見ると確かにデータが修正されているのが確認できます。
修正データの確認

削除処理(D)を作成する

CRUDのDelete、つまり削除処理を作成します。ブログのタイトルと内容をデータベースから削除します。
一覧画面に削除用のリンクを追加して、このリンクが押されると削除するデータが表示されます。この画面には削除ボタンも表示されていて、このボタンがクリックされると削除処理がされるようにします。

コントローラを編集する

app\Http\Controllers\ArticleController.phpに削除用のメソッドを追加します。削除用のメソッドは削除データを表示するメソッド(show)とデータベースからデータを削除するメソッド(delete)の2つを追加します。

showメソッドは修正のときと同様にidを受け取りこのデータを抽出してビューに渡します。
deleteメソッドはidを受け取って、そのidのデータをデータベースから削除しています。削除にはdestroyメソッドを使用しています。

ルーティングを設定する

「インストールしたURL/delete/XX」のアクセスをArticleコントローラのshowメソッドに割り当てています。これは修正のときと同じようにURLに指定されたデータをshowメソッドにidとして渡しています。
routes\web.phpを以下のコードに修正します。

ビューを作成する

一覧画面のresources\views\article\index.blade.phpファイルに削除用のフォーム画面へのリンクを追加します。

20行目で削除画面へのリンクを追加しています。リンク先が「/delete/id」となるように生成しています。

削除用の表示画面resources\views\article\show.blade.phpファイルと、削除完了の表示画面resources\views\article\delete.blade.phpファイルを作成します。

データは単に表示させるだけですので、edit.blade.phpとは異なりreadonlyで修正できないようにしています。フォーム部品を使用せずに表示するだけでもよいですがここではedit.blade.phpを流用する形にしています。

動作を確認する

一覧画面から削除画面
一覧画面から削除リンクをクリックして削除画面にリンクします。
削除画面
削除対象のデータが表示されます。確認して削除ボタンをクリックします。
削除完了画面
データベースの中身を見ると確かにデータが修正されているのが確認できます。
削除データの確認

改良ポイント

このチュートリアルはあくまで簡単にCRUDをつくってみるというスタンスですので、このままでは業務レベルのアプリケーションには当然なりえません。いくつか改良すべきポイントがあります。
改良すべきポイントは後日このブログで紹介していこうと思っていますので、ここではポイントを列挙するだけにとどめたいと思います。

認証機能

このままでは誰でもブログのデータをかけてしまいますので、ログインした人だけ書けるような機能が当然必要になります。

テンプレート

今回作成したビューファイルは全部で7ファイルありますが、その全てで共通の部分がかなりあります。例えばHTMLのhead部分などです。Laravelでは共通部分をテンプレートとして扱う便利な機能があり普通はこれを使うことが多いと思います。今回のチュートリアルでは触れていませんので、この機能も後日紹介していきたいと考えています。

バリデーション

今回のチュートリアルではフォーム入力値のチェックを行っていません。Webアプリとしては当然必要な機能になります。Laravelでは強力なバリデーション機能がありますのでこちらも後日紹介していきたいです。

ページング

登録データ数が増えると一覧画面の表示がいっぱいになってきます。通常はこういう場合ページ分けをします。Lavaelではページングの機能がありますのでこちらも後日紹介していきたいです。

その他

その他にも、新規追加と修正は同じくくりで扱えるようにしたほうが良いとか、登録完了時に一覧にリダイレクトしたほうがいいとか、データ検索は?とかいろいろ細かいところは唸るほどあると思います。
こうした方が、ということがありましたらコメントいただければブログのネタにさせていただきます。