この記事の解説は独自の解釈が多いため間違っている可能性もあります。そのような箇所があれば指摘して頂けると幸いです。
目標
ログイン機能付きのサイトを作るために必要なLaravel
の基礎を習得する
環境
- Windows 10 home
- XAMPP
- Laravel
Laravelの勉強
まずは初心者のためのLaravel入門 - libroを軸に勉強を進めていく。
学習の手順としては入れ替えた方が良い箇所もあるかもしれないが、自分にとって親しみやすい順で進めていく。
Laravelのインストール
Composerのインストール
Laravel
のインストールにはComposer
というパッケージ管理ツールを使う。
PHP
で使用するソフトウェアやアプリケーションをインストールしたい時に、そのソフトウェアなどが動くのに必要な依存関係のある他のソフトウェアなども一緒にインストールしてくれる便利なツール。
Composer 公式からダウンロードして、PATH
を通して、ターミナルなどで次のような表示がされればOK。
Laravelインストーラーの導入
Laravel
では設定ファイルやコードなどを1つのプロジェクトとしてまとめて作業を行う。
ディレクトリやフォルダと同じ認識。
では、Laravel
のプロジェクトを作成していく。
今後もLaravel
プロジェクトを作成することを考えて、Composer
でLaravelインストーラーを導入してからLaravel
のプロジェクトを作成する。
Laravelインストーラーは下記のコマンドをターミナル実行して、インストールする。
$ composer global require "laravel/installer"
Laravelインストーラーのダウンロードが終わったら、赤下線部分をエクスプローラーで開く。
そこから~\vendor\bin
まで移動し、そこまでのパスをコピーする。
C:\(各自のパス)\AppData\Roaming\Composer\vendor\bin
その後、Windows10
の左下にある検索窓から「環境変数」を入力してシステム環境変数の編集
を開く
システムのプロパティ
が開けたら下の環境変数
(赤枠部)をクリック。
その後、下にあるシステム環境変数(S)
からPath
を探してダブルクリック。
すると、環境変数名の編集
が開けるので、右上の新規
をクリックし、先程のパスを貼り付けて、OK
を押す。
Laravelプロジェクトの作成
ターミナルに戻り、下記コマンドを実行。
$ laravel new blog(プロジェクト名)
これでLaravel
のプロジェクトが作成される。
今後、Laravel
のプロジェクトを作成したいときは、$ laravel new (プロジェクト名)
をターミナルで実行するだけで作成できるようになった。
作成できたプロジェクトを実際に実行してみる。
ターミナルから以下のコマンドを実行。
$ cd (プロジェクト名)
$ php artisan serve
$ php artisan serve
でLaravel
の内蔵サーバーを起動できる。
つまり、このコマンドを利用することでローカルのアプリケーションとしてプロジェクトの状態確認が可能に。
ターミナルに表示された http://127.0.0.1:8000 にアクセスしてみると、Laravel
と中央に大きく書かれたサンプルページが開かれる。
ターミナルでCtrl + C
を押すとサーバーを閉じる。
プロジェクト(フォルダ)構成について
プロジェクトを作成した際、一緒にインストールされたファイルなどはLaravelをスタートしよう(4/5):初心者のためのLaravel入門 - libroに解説が載っている。
ただ、この記事の情報は古いため、必要があれば下記コマンドでLaravel
のバージョンなどを確認し、公式ドキュメントなどで各自フォルダ構成について調査を。
$ php artisan --version
ルーティング処理
ルーティング処理: どのアドレスでアクセスされたら、どの処理を返すかを定義するもの
Laravel
では(プロジェクト名)\routes\web.php
でルーティング処理が指定されており、実際にファイルを確認してみると、以下のような宣言がある。
Route::get('/', function () {
return view('welcome');
});
上記のコードをRoute::メソッド(第一引数, 第二引数)
として解説を行う。
-
Route
: クラス名。::
の後に続くメソッドを呼び出して処理を実行する。 -
メソッド
:Route
クラスで定義されている処理から、どの処理を実行するかを指定する。ここによって次の第一引数
の値が変わる。 -
第一引数
:メソッド
によって値が変わる。(例:get
メソッドではアドレスを表すテキスト。group
メソッドではアドレス情報をまとめた配列になる) -
第二引数
:第一引数
にアクセスされた際に返す処理。web.php
ではファイル名が指定されているがテキストなども返すことができる。
以上の解説を踏まえて、現在のweb.php
を見てみると、/(ルート)
にアクセスされたらview(welcome)
を返すルーティング処理であることがわかる。
このルーティング処理で呼び出されるview(welcome)
がどこにあるか、どのファイルかという質問に対する答えは、(プロジェクト名)\resources\views\welcome.blade.php
。
view()
関数については次章で説明する。
welcome.blade.php
にblade
という見慣れない拡張子があるが、これはLaravel
で利用できるテンプレートの仕組み。
この仕組みを利用することで、blade
拡張子がついたファイル同士でコードを共有しあったり、Laravel
に搭載されている機能を簡単に呼び出したりすることができるようになる。
ルーティング処理についてわかったところで、Hello,World!!
を表示するようにweb.php
を変更してみる。
この後の作業で使用するため、変更前のコードをコメントアウトなどして残しておく。
Route::get('/', function () {
return 'Hello,World!!';
});
表示用のファイル(テンプレート)について
web.php
で特定のURLにアクセスされた際の処理を定義できることが分かった所で、その結果を表示するページを作成していく。
今回は簡単なPHP
ファイルを作成するが、welcome.blade.php
のようなファイルを作成することもある。むしろ、そちらが主流。そのような.blade.php
拡張子ファイルはテンプレートと呼ばれ、この先で作成するため覚えておいてほしい。
では、表示用のページとなるファイルから作成していく。
(プロジェクト名)\resources\views\
にtemplate.php
を作成し、下記の内容にする。
<!DOCTYPE HTML>
<html>
<head>
<title>template</title>
<style>
body{color:gray;}
h1{font-size:18pt; font-weight:bold;}
</style>
</head>
<body>
<h1>Template</h1>
<p><?php echo $message; ?></p>
</body>
</html>
次に、web.php
でこのファイルをを表示するルーティング処理を定義する。
Route::get('/template', function () {
return view('template',['message' => 'Study Template']);
});
ルーティング処理の内容は**/template
にアクセスされたらtemplate.php
を返す**というものだが、view()
の中に連想配列が指定されている。
ここでルーティング処理
の所で飛ばしたview()
関数の説明をする。
view()
関数は**view(第一引数, 第二引数)
**という形をとり、次のように宣言する。
-
第一引数
: ファイル名、テンプレート名を指定する。拡張子を除いた名前を宣言する。 -
第二引数
:第一引数
に渡す値などを指定する。今回では連想配列を用いて、template.php
の変数$message
にStudy Template
という文字列を渡している。
以上のファイル、ルーティング処理の作成によって表示されるページは次のようなものとなる。
http://127.0.0.1:8000/template
コントローラー
(プロジェクト名)\routes\web.php
にルーティング処理を定義することで、(プロジェクト名)\resources\views\
にある表示用のファイルやテンプレートを呼び出せるようになったがある問題が潜んでいる。
それはview()
の第二引数を利用する処理が増えると、web.php
のコードが複雑になることだ。
テンプレートの作成では第二引数に指定する連想配列のキーと値は1つだけだったが、web.php
で宣言するルーティング処理が増え、連想配列の数も増えれば見づらく、読みにくいコードとなってしまう。
そのような問題を防ぐために使用されるのがコントローラーだ。
実際に作成しながら解説をしていく。
コントローラーは(プロジェクト名)\app\Http\Controllers
に作成する。
今回はその階層にTemplateController.php
というファイルを作成し、次の内容にする。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class TemplateController extends Controller
{
public function getIndex()
{
return view('template', ['message' => 'Study Template']);
}
}
?>
そして、web.php
のRoute::get('/template', ~
を下記のように変更する。
Route::get('/template','TemplateController@getindex');
Route
クラスの第二引数に指定されている**TemplateController@getindex
でTemplateController
のgetIndex()
メソッドを呼び出す**ことを宣言している。
TemplateController.php
のようなコントローラーの仕組みを説明をしていく。
新規作成したコントローラーのファイルでは**use App\Http\Controllers\Controller;
でApp\Http\Controllers\Controller
というクラスを継承することを忘れずに**宣言する。
public function getIndex()
で宣言されているgetIndex()
は、Route::get()
などのGET
アクセスでindex
というアドレスにアクセスした際に呼び出されるメソッドであることを定義している。
このTemplateController.php
自体がweb.php
のルーティング処理において、Route::get()
で/template
に割り当てられているため、/template/index(トップページ)
にアクセスすると、getIndex()
が呼び出され、view()
で定義した処理が実行される仕組みとなっている。
コントローラーで指定するメソッド(getIndex()
など)はHTTPメソッドの種類 + アクセスするアドレスによって名前が自動的に決まるため、このルールを覚えておく必要がある。
http://127.0.0.1:8000/template にアクセスして、エラーが表示されていないか確認。
Requestクラス
ここではRequest
クラスを利用して、フォームを使用したページ間でのデータの送受信ができるようにする。
この記事の軸にしていたサイトの情報が古かったので、ここではLaravel5 チュートリアル ブログもどきを作る(2) ブログ記事投稿フォームの作成 - Qiitaをメインに進めていく。
まずはテンプレートの作成から。
GET
メソッド以外でフォームを利用する場合、Laravel
の仕様でCSRF(ログイン状態で悪意あるURLにアクセスするとログイン情報が盗まれ悪用される事)
の対策をしないとエラーが発生する。
その対策として活用できるのがLaravel
の機能であるblade
テンプレートだ。
(プロジェクト名)\resources\views\
にform.blade.php
を作成し、次の内容にする。
<!DOCTYPE HTML>
<html>
<head>
<title>Form</title>
<style>
body{color:gray;}
h1{font-size:18pt; font-weight:bold;}
</style>
</head>
<body>
<h1>フォームを利用したデータの送受信</h1>
<p>{{ $message }}</p>
<form method="POST" action="/form">
{{ csrf_field() }}
<input type="text" name="str">
<input type="submit">
</form>
</body>
</html>
{{ }}
がblade
テンプレートの記法。
{{}}
自体は<?php echo ~ ?>
の代わりで、{{ csrf_field() }}
はこれだけでLaravel
におけるCSRF
対策の機能を呼び起こし、利用できる。
続いて、コントローラーを作成する。
(プロジェクト名)\app\Http\Controllers
にFormController.php
を作成し、次の内容にする。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class FormController extends Controller
{
public function getIndex(Request $request)
{
return view('form', ['message' => 'データを入力してください。']);
}
public function postIndex(Request $request)
{
$res = "入力内容: ".$request -> input('str');
return view('form', ['message' => $res ]);
}
}
?>
postIndex()
はテンプレートの章でも説明したように、POST
アクセスでindex
に接続した際に実行される処理がそれ以降に記載されている。
そのため、POST
アクセスが行われていない何もデータが入力されていない時に表示する用のページとして、getIndex()
のメソッドも作成しておくことも必要。
そして、今回の主題となるのが**Request
クラスを利用した(Request $request)
**だ。
Request
クラスではユーザーからのアクセスを始めとする各種情報を管理している。
その内容を$request
に入れ、今回はinput('str')
という形でデータを取り出している。
input
に関するデータはinput(name属性)
で取り出せるため、このような記述となる。
(プロジェクト名)\routes\web.php
に次のルーティング処理を追記する。
Route::get('/form','FormController@getindex');
Route::post('/form','FormController@postindex');
ここで意図した設計で稼働しているか確認してみる。
http://127.0.0.1:8000/form にアクセス。
この状態で送信
を押すと、
このように変化する。
Requestクラスの基本(3/5):初心者のためのLaravel入門 - libro 以降ではクエリやURLの取得、リダイレクトについて記載されているため、確認してみては。
データベースとの連携
ここではXAMPP
のMySQL
を利用して、Laravel
とデータベースを連携させる。
まずはデータベースの準備から。
XAMPP
を起動したら、XAMPP
のコントロールパネルにおけるMySQL
のAdmin
をクリックして、phpMyAdmin
に接続する。
phpMyAdmin
にログインできたら、データベース
タブから下記画像のように新規データベースを作成する。(画像ではデータベース名が頭文字が大文字だったが作成したら小文字になった。)
そして、新規テーブルを作成する。
好きな名前とカラム数を設定してテーブルを作成し、
ここまで(↓)設定できたら、次はLaravel
側の設定に移る。
今回はMySQL
を使用するが、他のデータベースを利用したい場合は、(プロジェクト名)\config\database.php
を開いて、下記の部分を使用したいデータベースに変える。
'default' => env('DB_CONNECTION', 'mysql'),
どのデータベースを使用するか設定できたら、(プロジェクト名)\.env
を開いて、下記にデータベース情報を入力していく。
デフォルトで値が入っているが、必要があれば変更する。
DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
ここからはデータベースに接続し、値を取得、ページに表示するまでを説明していく。
コントローラーの作成から行っていく。
(プロジェクト名)\app\Http\Controllers
にDatabaseController.php
を作成し、下記の内容にする。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class DatabaseController extends Controller
{
public function getIndex(Request $request)
{
$data = DB::select('select * from sample');
return view('database', ['message' => 'データベース名: sample','data' => $data]);
}
}
?>
use DB;
を忘れないように注意。
DB::select
はデータベースに対してSELECT
のクエリ文を実行するための関数。
select
以外にもDB
クラスにはデータベースを操作するためのメソッドがあり、それらを CRUD処理
と呼ぶ。
CRUD処理
とは、Create(生成)
, Read(読み取り)
, Update(更新)
, Delete(削除)
の処理における頭文字を並べたもの。
それぞれのDB
クラスにおけるメソッドは**Create(生成) = DB:insert()
** , Read(読み取り) = DB:select()
, Update(更新) = DB:update()
, Delete(削除) = DB:delete()
となるので覚えておく。
余談となるが、複数人がページやサイトにアクセスしていて、同時にデータベースにCRUD処理
を実行した場合、Update
とDelete
が同時に実行する命令が起きるようなデータの不整合が起きる可能性がある。
そのような事態に陥るのを防ぐために行われるのが トランザクション
で、DB::beginTransaction();
から DB::commit();
の間に書かれた処理が実行されている間は他の命令が実行されることを防ぐことができるようになる。
本番環境でデータの書き換えを行うような処理を定義する場合は忘れずに記述するようにしておく。
本題に戻って、コントローラーが取得したデータベースのデータを表示するページを作成していく。
(プロジェクト名)\resources\views\
にdatabase.blade.php
を作成し、下記のような内容に。
<!DOCTYPE HTML>
<html>
<head>
<title>Form</title>
<style>
body{color:gray;}
h1{font-size:18pt; font-weight:bold;}
th{color:white; background:#999;}
td{color:black; background:#eee; padding:5px 10px;}
</style>
</head>
<body>
<h1>Laravelとデータベースの連携</h1>
<p>{{ $message; }}</p>
<table>
<tr>
<th>ID</th>
<th>NAME</th>
<th>PASS</th>
<th>CREATE_DAY</th>
</tr>
@foreach($data as $value)
<tr>
<td>{{ $value -> id; }}</td>
<td>{{ $value -> name }}</td>
<td>{{ $value -> pass }}</td>
<td>{{ $value -> create_day }}</td>
</tr>
@endforeach
</table>
</body>
</html>
@foreach($data as $value)
でコントローラーが取得したデータベースの各値が入っている$data
を$value
に移す。
{{ $value -> (カラム名) }}
で各カラムに入っているデータを取得して表示している。
(プロジェクト名)\routes\web.php
に今回のルーティング処理を実装して、実際にページを確認してみる。
Route::get('/database','DatabaseController@getindex');
自分の今までに掲載した画像の設定と同じ設定にすれば次のように表示されるはず。
http://127.0.0.1:8000/database
ORM(Object/Relational Mapping)について
さっきは自分でデータベースを作成して値を取得、表示まで行ったが、仕事でも同じような状況で作業ができるとは限らない。
違う人がデータベースを作成する事なんて普通だし、そもそもデータベースを見れずに手探りでデータを取得しなければならないことだってあり得る。
そのような状況で、今までのようなやり方では不都合が多い。
そこでPHP
のようなオブジェクト指向言語で用いられる技術が ORM(Object/Relational Mapping)
だ。
この技術を用いることで、データベースのテーブルに存在しているデータ、値をPHP
のオブジェクトに変換したり、その逆の変換も行えるようになる。
その上、PHP
側で用意したクラスを操作するだけで、それに対応するデータベースのテーブルを自動的に操作できるようになるという。
Laravel
では Eloquent
というORM
が利用できるため早速使用してみる。
最初にテーブルに対応するモデルと呼ばれるクラスの作成を行う。
ターミナルでプロジェクトのトップディレクトリに移動し、下記コマンドを実行。
自分はどのテーブルを扱うのかわかりやすいよう、テーブル: sample
に対し、モデル: Sample
を作成した。
$ php artisan make:model Sample(モデル名)
上記のコマンドが成功すると、(プロジェクト名)\app
にSample(モデル名).php
が作成されているので、開いて確認してみると次のような内容になっている。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sample extends Model
{
//
}
//
とコメントアウトにされている箇所があるが、そこを protected $table = 'sample';
に変更して、使用するテーブル名を定義する。
protected
を付けることで、そのクラス自身と継承したクラス限定でアクセスが可能となるため、テーブルを保護するためにも欠かさずに付与する。
モデルの作成はこれで完了。コントローラーの作成に移る。
(プロジェクト名)\app\Http\Controllers
にORMController.php
を作成し、下記の内容を入力する。
データベースとの連携で使用した表示用のファイル(プロジェクト名)\resources\views\database.php
を使用するため、view()
関数の第一引数はdatabase
にする。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sample;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class ORMController extends Controller
{
public function getIndex(Request $request)
{
$data = Sample::all();
return view('database', ['message' => 'データベース名: sample','data' => $data]);
}
}
?>
use App\Sample;
で今回作成したモデルを使用することを宣言。
Sample::all()
では、Sample
クラスでモデル: Sample
に対応しているテーブル: sample
の全データをall
メソッドを使用して取得している。
一回ここで、モデルなどが問題なく使えているか確かめる。
(プロジェクト名)\routes\web.php
にルーティング処理を実装し、実際にページを確認してみる。
Route::get('/orm','ORMController@getindex');
http://127.0.0.1:8000/orm にアクセスしてみて、http://127.0.0.1:8000/database と同じ内容が表示されているか確かめる。
all
の他にもデータベースにおける処理に関するメソッドがモデルクラスには用意されている。
その中の一つが検索機能の where
だ。
where
は モデル名::where(カラム名, 取得したい値)
でテーブルに検索をかけて、 get()
でその結果を取得する。
コントローラーに実装して、試してみるとそれぞれ次のようになる。
class ORMController extends Controller
{
public function getIndex(Request $request)
{
$data = Sample::where('id', 2)->get();
return view('database', ['message' => 'データベース名: sample','data' => $data]);
}
}
?>
検索を実行できるwhere
には様々な使い方がある。
>
やlike
といった演算子を使いたい場合は where(カラム名, 演算子, 取得したい値)
、and
条件なら where(条件1) -> where(条件2)
、or
条件なら where(条件1) -> orWhere(条件2)
という風になる。
データベースから値を取得する機会は多いので、少なくともこれらだけでも覚えておきたい。
Laravelからデータベースのデータを操作する
CRUD処理
において、Read
に関してはORM
のwhere
で触れたが、Create
とUpdate
,Delete
がまだなので、今回はそれらに触れていく。
前準備
ORM
の際に作成したモデルに2つのコードを追加する。
class Sample extends Model
{
protected $table = 'sample';
protected $guarded = array('id');
public $timestamps = false;
}
protected
はテーブルだけでなく、データも保護できる。
protected $guarded = array('id');
で主キーを保護する。
更新や削除の際にprotected
で保護されていないと、連携しているテーブルにも影響を与えてしまう。
それらを防ぐためにもテーブルや主キーには protected
で忘れずに保護をかける。
Laravel
でデータベースにデータを作成、追加する際、create_at
,update_at
という、それぞれ作成日時と更新日時を示す項目が自動的に作成される。
今回利用するテーブルではこれらの項目を設けていないため、何もしない状態でデータベースにデータを作成、追加してしまうと、エラーの原因となる。
それを防ぐのが public $timestamps = false;
の部分。
このコードを追加することで、データベースにデータを作成、追加する際にcreate_at
,update_at
が生成されなくなる。
データベースにデータを作成、追加する処理をLaravel
に実装する際は、このコードを追加するかテーブルにcreate_at
,update_at
カラムの作成を忘れないように。
Create
表示用のページとして(プロジェクト名)\resources\views\
にcreate.blade.php
を作成し、次のような内容に。
<!DOCTYPE HTML>
<html>
<head>
<title>CRUD</title>
<style>
body{color:gray; }
h1{font-size:18pt; font-weight:bold;}
th{color:white; background:#999;}
td{color:black; background:#eee; padding:5px 10px;}
</style>
</head>
<body>
<h1>LaravelからのCRUD処理</h1>
<p>{{ $message }}</p>
<table>
<tr>
<th>ID</th>
<th>NAME</th>
<th>PASS</th>
<th>CREATE_DAY</th>
</tr>
@foreach($data as $value)
<tr>
<td>{{ $value -> id }}</td>
<td>{{ $value -> name }}</td>
<td>{{ $value -> pass }}</td>
<td>{{ $value -> create_day }}</td>
</tr>
@endforeach
</table>
<table>
<form method="post" action="/create">
{{ csrf_field() }}
<tr><td>NAME:</td><td><input type="text" name="name"></td></tr>
<tr><td>PASS:</td><td><input type="text" name="pass"></td></tr>
<tr><td>CREATE_DAY:</td><td><input type="text" name="day"></td></tr>
<tr><td></td><td><input type="submit"></td></tr>
</form>
</table>
</body>
</html>
大まかな内容としては、テーブルのデータを表示して、post
で作成するデータを送信するというもの。
ID
に値する内容を入力するフォームを作成していないが、これはデータベースのAUTO_INCREMENT
を利用しているため。
AUTO_INCREMENT
とは他のデータが挿入された際に、適用しているカラムに自動でデータを入力してくれるデータベースの機能。
この機能を適用させるには、phpMyAdmin
を開いて、AUTO_INCREMENT
を適用したいカラムを選択して、変更
をクリック。
その後、A_I
の下のチェックボックスにチェックを入れ、保存。
もし、使用しない場合はID
の値を入力するフォームを作成を忘れないように。
post
から投げられたデータはコントローラーでデータベースのテーブルに挿入する。
その処理は以下のような内容。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\Sample;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class CreateController extends Controller
{
public function getIndex(Request $request)
{
$data = DB::select('select * from sample');
return view('create', ['message' => 'Create処理を実行する','data' => $data]);
}
public function postIndex(Request $request)
{
$name = $request -> input('name');
$pass = $request -> input('pass');
$day = $request -> input('day');
$data = array(
'name' => $name,
'pass' => $pass,
'create_day' => $day
);
Sample::create($data);
return redirect()->action('CreateController@getindex');
}
}
?>
データベースのテーブルにデータを作成する処理、Create
ではモデル名::create()
メソッドを使用する。
getIndex()
はデータベースの連携の際の内容と同じなので説明を省略。
postIndex()
はpost
が実行されたときに行われる処理を示している。
input
に入力されたname
,pass
,day
を$data
という連想配列に格納して、モデル名::create($data)
で$data
の内容をデータベースのテーブルに格納。
その後、getIndex()
にリダイレクトするという流れになっている。
最後に(プロジェクト名)\routes\web.php
に下記のルーティング処理を実装し、実際にページを確認してみる。
Route::get('/create','CreateController@getindex');
Route::post('/create','CreateController@postindex');
post
後(ID
の5,6が抜けてるのは作成中にエラーの対応をしていたため)
Update
表示用のページとして(プロジェクト名)\resources\views\
にupdate.blade.php
を作成し、form
以下を次の内容に。
それ以外はCreate
で作成したcreate.blade.php
と同じ。
<form method="post" action="update">
{{ csrf_field() }}
<tr>
<td>ID:</td>
<td>
{{ optional($data)->id }}
<input type="hidden" name="id" value="{{ optional($data)->id }}">
</td>
</tr>
<tr>
<td>NAME:</td>
<td><input type="text" name="name" value="{{ optional($data)->name }}"></td>
</tr>
<tr>
<td>PASS:</td>
<td><input type="text" name="pass" value="{{ optional($data)->pass }}"></td>
</tr>
<tr>
<td>CREATE_DAY:</td>
<td><input type="text" name="day" value="{{ optional($data)->create_day }}"></td>
</tr>
<tr>
<td></td>
<td><input type="submit"></td>
</tr>
</form>
id
以外の各カラムの更新内容を入力するフォームを作成。
optional()
は引数に指定したオブジェクトにアクセスしたり、そのプロパティを取得する 関数。
オブジェクトがnull
の時はnull
を返す。
post
から投げられたデータをデータベースに更新する処理を記述するコントローラーのclass
以下は次のような内容。
class
より上はCreate
で作成したcreate.blade.php
と同じ。
class UpdateController extends Controller
{
public function getIndex(Request $request)
{
$id = $request -> id;
$table = DB::select('select * from sample');
$data = Sample::find($id);
$msg = 'Update Sample Table [id = ' . $id . ']';
return view('update', ['message' => $msg,'Table' => $table,'data' => $data]);
}
public function postIndex(Request $request)
{
$id = $request -> input('id');
$data = Sample::find($id);
$data -> name = $request -> input('name');
$data -> pass = $request -> input('pass');
$data -> create_day = $request -> input('day');
$data->save();
return redirect()->action('UpdateController@getindex');
}
}
$id = $request -> id;
でURL
におけるクエリパラメータ(~/~?id=123
などの?
以降の部分)を取得している。
そこで取得した$id
を モデル名::find()
の引数に使用することで、引数に一致するレコードをデータベースから取得し、$data
などのインスタンスに格納できるようにしている。
データベースのテーブルにおけるデータを更新する際は save()
メソッドを使用する。
(プロジェクト名)\routes\web.php
に下記のルーティング処理を実装し、実際にページを確認してみる。
Route::get('/update','UpdateController@getindex');
Route::post('/update','UpdateController@postindex');
post
前: http://127.0.0.1:8000/update?id=7
フォームの内容を変更したい内容に変えてある。
Delete
表示用のページとして(プロジェクト名)\resources\views\
にdelete.blade.php
を作成し、form
を次の内容に。
それ以外はCreate
で作成したcreate.blade.php
と同じ。
<form method="post" action="update">
{{ csrf_field() }}
<tr>
<td>削除したいレコードのID:</td>
<td>
<input type="text" name="id" value="{{ optional($data)->id }}">
</td>
</tr>
<tr>
<td></td>
<td><input type="submit"></td>
</tr>
</form>
削除したいレコードのIDを入力するフォームと送信ボタンだけでOK。
指定されたレコードをデータベースから削除する処理を記述するDeleteController.php
は次のような内容。
class
より上はCreate
で作成したcreate.blade.php
と同じ。
class DeleteController extends Controller
{
public function getIndex(Request $request)
{
$data = DB::select('select * from sample');
return view('update', ['message' => 'レコードの削除','data' => $data]);
}
public function postIndex(Request $request)
{
$id = $request -> input('id');
$data = Sample::find($id);
$data -> delete();
return redirect()->action('DeleteController@getindex');
}
}
Create
,Update
で使用したコントローラーの内容がわかっていれば $data -> delete();
以外説明することもない。
$data -> delete();
も Update
で使用したsave()
メソッドと同じような使い方をして、そのデータを削除する使い方をするものだという覚え方で問題はない。
いつも通り、(プロジェクト名)\routes\web.php
に下記のルーティング処理を実装し、実際にページを確認してみる。
Route::get('/delete','DeleteController@getindex');
Route::post('/delete','DeleteController@postindex');
post
前: http://127.0.0.1:8000/delete
番外編: バリデーション
CRUD処理
の番外編としてバリデーションにも触れていく。
この機能は入力内容をチェックし、設定した条件を満たしているかどうかを判断するもので実装する方法は複数あるが、今回はフォームのバリデーションを実装する。
フォームのバリデーションはLaravel
において、フォームリクエストと呼ばれる。
今回はUpdate
で使用したファイル達に、このフォームリクエストを適用していく。
フォームリクエストは以下のコマンドをターミナルで実行して作成する。
$ php artisan make:request UpdateRequest(作成したいファイル名)
処理が完了すると(プロジェクト名)\app\Http\Requests
にUpdateRequest(作成したいファイル名).php
が作成される。
UpdateRequest(作成したいファイル名).php
の各メソッドを次のように変更する。
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:10',
'pass' => 'required',
'day' => 'required|string|max:10',
];
}
バリデーションする条件の指定は、このように連想配列の形をとる。
どのような条件が指定できるかは公式ドキュメントに記載されているため、必要があれば確認を。
そしたら、(プロジェクト名)\app\Http\Controllers\UpdateControllers.php
に作成したバリデーションを適用させていく。
use App\Http\Requests;
use App\Http\Requests\UpdateRequest;
// 中略
public function postIndex(UpdateRequest $request)
{
変更といっても、use
の箇所に use App\Http\Requests\UpdateRequest;
を追加、public function postIndex(Request $request)
を public function postIndex(UpdateRequest $request)
に変えるだけ。
これで http://127.0.0.1:8000/update?id=4 にアクセスして、フォームの中を全て空にして送信
を押すと、最初の状態に戻り、バリデーションが効いていることがわかる。
ただ、エラーメッセージもなしに画面が遷移するのはわかりにくいので、表示用のページである(プロジェクト名)\resources\views\update.blade.php
も変更する。
// 略
.alert{color:red;}
</style>
</head>
// 中略
</table>
@if ($errors->any())
<div class="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
</body>
これでバリデーションが適用された際、どのフォームが条件を満たしていないかが赤字で表示されるようになった。
Laravel
からテーブルを操作する
ここまででLaravel
側からデータベースのテーブルに対する操作ができることを学んだが、Laravel
ではテーブルそのものを作成することもできる。
ここからはLaravel入門 - 使い方チュートリアル - - QiitaとLaravel5 チュートリアル ブログもどきを作る(1) DB設定・マイグレーション - Qiitaシリーズを軸に進めていく。
マイグレーション
Laravel
のテーブルそのものを作成する仕組み、それが マイグレーション
だ。
まずはデータベースにテーブルを作成するためのマイグレーションファイルを作成するところから始まる。
今回はlaravels
というテーブル名で、それを作成するためのマイグレーションファイルを以下のコマンドをターミナルに入力して作成する。
テーブル名の最後にs
を忘れないように。
$ php artisan make:migration laravels(作成したいマイグレーションファイル名) --create=laravels(作成したいテーブル名)
そうすると、(プロジェクト名)\database\migrations
に2020_08_06_095118_laravels(作成したいマイグレーションファイル名).php
が作成される。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Laravels extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('laravels', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('laravels');
}
}
public function up()
にはテーブルを作成するときの処理が、public function down()
にはテーブルを削除する処理が記載されている。
このまま、このファイルを実行してもテーブルを作成してもよいが、次のように少しカラムの設定を宣言してみる。
public function up()
{
Schema::create('laravels', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 10);
$table->timestamps();
});
}
この状態でmigration
が実行されると、次の設定が反映されたカラムになる。
カラム名 | 設定 |
---|---|
id | AUTO_INCREMENT |
name | VARCHAR(10) |
create_at | timestamp |
update_at | timestamp |
上でも説明したように、create_at
とupdate_at
のカラムは自動で作成され、AUTO_INCREMENT
は自動挿入、timestamp
は日時が自動で挿入される機能。
では、このファイルを実行して、テーブルを作成してみる。
ターミナルに次のコマンドを入力することで、マイグレーションファイルが実行される。
$ php artisan migrate
migrate
でテーブルを作成するpublic function up()
の処理が行われた。
public function down()
の処理はmigrate:rollback
やmigrate:reset
で実行する。
migrate:rollback
は 最後に行ったマイグレーション操作を取り消す。
migrate:reset
は 全てのマイグレーションを削除する。
シーディング
シーディング
はテーブルの初期化やテストデータとなるレコードを挿入するLaravel
の仕組み。
今回はこの仕組みを利用して、マイグレーション
で作成したmigration
テーブルを初期化(最初のデータを挿入)する。
シーディング
もマイグレーション
同様、ファイルの作成から始めるが、その前にマイグレーションで作成したテーブルに対応するモデルの作成を行う。
$ php artisan make:model laravel(テーブル名の最後のs抜き)
マイグレーションの時のテーブル名における最後の文字にs
を付けてもらった理由がここにある。
モデル名はテーブル名の単数形にすることで自動的にテーブルを判断する機能がある。
テーブル名: 複数形
、**モデル名: 単数形
**の命名規則を忘れないように。
ファイルを編集する必要はないので(プロジェクト名)\app\
にlaravel(テーブル名の最後のs抜き).php
があるのを確認すればOK。
その後、ターミナルで下記のコマンドを実行。
$ php artisan make:seeder StudySeeder(作成したいシーディングファイル名)
そうすると、(プロジェクト名)\database\seeds
にStudySeeder(作成したいシーディングファイル名).php
が作成される。
<?php
use Illuminate\Database\Seeder;
class StudySeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}
migration
テーブルに挿入するデータは下の表。
id | name | create_at | update_at |
---|---|---|---|
1 | Laravel | 作成日時 | 作成日時 |
2 | Migration | 作成日時 | 作成日時 |
3 | Seeding | 作成日時 | 作成日時 |
StudySeeder(作成したいシーディングファイル名).php
で、この表の内容を入力できるようにするには次の内容にする。
public function run()
{
DB::table('laravels')->truncate();
$table_data = [
['name' => 'Laravel'],
['name' => 'Migration'],
['name' => 'Seeding']
];
foreach($table_data as $data) {
\App\laravel::create($data);
}
}
DB::table('laravels')->truncate();
でシーディングの対象となるテーブルの指定と初期化。
$migrationdata~
には連想配列の形式で入力したいレコードのデータを挿入。id
,create_at
,update_at
は自動挿入されるようにテーブル側で設定されているため、name
カラムだけ指定。
foreach($table_data as $data)~
で挿入するデータを一つずつテーブルに挿入していく。
\App\laravel::create();
のlaravel
部分は各自のモデル名に。
シーディングではコマンド実行時に同じディレクトリにあるDatabaseSeeder.php
を実行するため、このファイルも編集する。
public function run()
{
$this->call(StudySeeder::class);
}
StudySeeder
の部分を各自のシーディングファイル名に変更。
以上で設定は終わりなのでシーディングを実行してみる。
シーディングの実行はターミナルで次のコマンドを叩く。
$ php artisan db:seed
Laravelシステム作成手順
今回の学習を踏まえてLaravel
の作成手順をまとめる。
0. (プロジェクト名)\.env
にデータベース設定を記述
1. マイグレーションでテーブルを作成
2. シーディングでテーブルにデータ挿入
3. (プロジェクト名)\resources\views\
に表示用のファイル、blade
テンプレートを使用したファイルを作成
4. (プロジェクト名)\app\Http\Controllers\
に3で作成したファイルへデータなどを渡すコントローラーを作成
5. バリデーション作成
6. (プロジェクト名)\routes\web.php
でルーティング処理
次回の記事
今回はLaravel
で簡易的なサイトが作れるようになるまでの基礎を学んだ。
次回の記事から、実際に作業をしながらLaravel
の機能を学んでいく。
Laravelでログイン機能付きサイト作成 with XAMPP(2/4) 認証機能の有効化編
参考資料
- 初心者のためのLaravel入門 - libro
- Laravel - Laravelで「"Attribute [controller] does not exist."」というエラーに困ってます。|teratail
- Laravel5 チュートリアル ブログもどきを作る(2) ブログ記事投稿フォームの作成 - Qiita
- PHPのアクセス修飾子public, protected, privateの違い | UX MILK
- 【Laravel】Trying to get property フィールド名 of non-objectについて – ネコと征く戦場
- 【Laravel5.8】FormRequestを使うとThis action is unauthorized.が吐き出される - Laravelとねころっけくん5.8
- Laravel入門 - 使い方チュートリアル - - Qiita
- Laravel5 チュートリアル ブログもどきを作る(1) DB設定・マイグレーション - Qiitaシリーズ