8
16

More than 1 year has passed since last update.

Laravelでログイン機能付きサイト作成 with XAMPP(1/4) 基礎学習編

Last updated at Posted at 2020-08-07

この記事の解説は独自の解釈が多いため間違っている可能性もあります。そのような箇所があれば指摘して頂けると幸いです。

目標

ログイン機能付きのサイトを作るために必要なLaravelの基礎を習得する

環境

  • Windows 10 home
  • XAMPP
  • Laravel

Laravelの勉強

まずは初心者のためのLaravel入門 - libroを軸に勉強を進めていく。
学習の手順としては入れ替えた方が良い箇所もあるかもしれないが、自分にとって親しみやすい順で進めていく。

Laravelのインストール

Composerのインストール

LaravelのインストールにはComposerというパッケージ管理ツールを使う。
PHPで使用するソフトウェアやアプリケーションをインストールしたい時に、そのソフトウェアなどが動くのに必要な依存関係のある他のソフトウェアなども一緒にインストールしてくれる便利なツール。
Composer 公式からダウンロードして、PATHを通して、ターミナルなどで次のような表示がされればOK。
screenshot.jpg

Laravelインストーラーの導入

Laravelでは設定ファイルやコードなどを1つのプロジェクトとしてまとめて作業を行う。
ディレクトリやフォルダと同じ認識。

では、Laravelのプロジェクトを作成していく。
今後もLaravelプロジェクトを作成することを考えて、ComposerでLaravelインストーラーを導入してからLaravelのプロジェクトを作成する。
Laravelインストーラーは下記のコマンドをターミナル実行して、インストールする。

$ composer global require "laravel/installer"

Laravelインストーラーのダウンロードが終わったら、赤下線部分をエクスプローラーで開く。
screenshot.jpg
そこから~\vendor\binまで移動し、そこまでのパスをコピーする。

C:\(各自のパス)\AppData\Roaming\Composer\vendor\bin

その後、Windows10の左下にある検索窓から「環境変数」を入力してシステム環境変数の編集を開く

システムのプロパティが開けたら下の環境変数(赤枠部)をクリック。
screenshot.jpg

その後、下にあるシステム環境変数(S)からPathを探してダブルクリック。
すると、環境変数名の編集が開けるので、右上の新規をクリックし、先程のパスを貼り付けて、OKを押す。

Laravelプロジェクトの作成

ターミナルに戻り、下記コマンドを実行。

$ laravel new blog(プロジェクト名)

これでLaravelのプロジェクトが作成される。
今後、Laravelのプロジェクトを作成したいときは、$ laravel new (プロジェクト名)をターミナルで実行するだけで作成できるようになった。

作成できたプロジェクトを実際に実行してみる。
ターミナルから以下のコマンドを実行。

$ cd (プロジェクト名)
$ php artisan serve

screenshot.jpg

$ php artisan serveLaravelの内蔵サーバーを起動できる。
つまり、このコマンドを利用することでローカルのアプリケーションとしてプロジェクトの状態確認が可能に。
ターミナルに表示された http://127.0.0.1:8000 にアクセスしてみると、Laravelと中央に大きく書かれたサンプルページが開かれる。
ターミナルでCtrl + Cを押すとサーバーを閉じる。

プロジェクト(フォルダ)構成について

プロジェクトを作成した際、一緒にインストールされたファイルなどはLaravelをスタートしよう(4/5):初心者のためのLaravel入門 - libroに解説が載っている。
ただ、この記事の情報は古いため、必要があれば下記コマンドでLaravelのバージョンなどを確認し、公式ドキュメントなどで各自フォルダ構成について調査を。

$ php artisan --version

ルーティング処理

ルーティング処理: どのアドレスでアクセスされたら、どの処理を返すかを定義するもの

Laravelでは(プロジェクト名)\routes\web.phpでルーティング処理が指定されており、実際にファイルを確認してみると、以下のような宣言がある。

(プロジェクト名)\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.phpbladeという見慣れない拡張子があるが、これはLaravelで利用できるテンプレートの仕組み。
この仕組みを利用することで、blade拡張子がついたファイル同士でコードを共有しあったり、Laravelに搭載されている機能を簡単に呼び出したりすることができるようになる。

ルーティング処理についてわかったところで、Hello,World!!を表示するようにweb.phpを変更してみる。
この後の作業で使用するため、変更前のコードをコメントアウトなどして残しておく。

(プロジェクト名)\routes\web.php
Route::get('/', function () {
    return 'Hello,World!!';
});

screenshot.jpg

表示用のファイル(テンプレート)について

web.phpで特定のURLにアクセスされた際の処理を定義できることが分かった所で、その結果を表示するページを作成していく。
今回は簡単なPHPファイルを作成するが、welcome.blade.phpのようなファイルを作成することもある。むしろ、そちらが主流。そのような.blade.php拡張子ファイルはテンプレートと呼ばれ、この先で作成するため覚えておいてほしい。

では、表示用のページとなるファイルから作成していく。
(プロジェクト名)\resources\views\template.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でこのファイルをを表示するルーティング処理を定義する。

(プロジェクト名)\routes\web.php
Route::get('/template', function () {
    return view('template',['message' => 'Study Template']);
});

ルーティング処理の内容は**/templateにアクセスされたらtemplate.phpを返す**というものだが、view()の中に連想配列が指定されている。

ここでルーティング処理の所で飛ばしたview()関数の説明をする。
view()関数は**view(第一引数, 第二引数)**という形をとり、次のように宣言する。

  • 第一引数: ファイル名、テンプレート名を指定する。拡張子を除いた名前を宣言する
  • 第二引数: 第一引数に渡す値などを指定する。今回では連想配列を用いて、template.phpの変数$messageStudy Templateという文字列を渡している。

以上のファイル、ルーティング処理の作成によって表示されるページは次のようなものとなる。
http://127.0.0.1:8000/template

screenshot.jpg

コントローラー

(プロジェクト名)\routes\web.phpにルーティング処理を定義することで、(プロジェクト名)\resources\views\にある表示用のファイルやテンプレートを呼び出せるようになったがある問題が潜んでいる。
それはview()の第二引数を利用する処理が増えると、web.phpのコードが複雑になることだ。
テンプレートの作成では第二引数に指定する連想配列のキーと値は1つだけだったが、web.phpで宣言するルーティング処理が増え、連想配列の数も増えれば見づらく、読みにくいコードとなってしまう。

そのような問題を防ぐために使用されるのがコントローラーだ。
実際に作成しながら解説をしていく。

コントローラーは(プロジェクト名)\app\Http\Controllersに作成する。
今回はその階層にTemplateController.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.phpRoute::get('/template', ~を下記のように変更する。

(プロジェクト名)\routes\web.php
Route::get('/template','TemplateController@getindex');

Routeクラスの第二引数に指定されている**TemplateController@getindexTemplateControllergetIndex()メソッドを呼び出す**ことを宣言している。

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を作成し、次の内容にする。

(プロジェクト名)\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\ControllersFormController.phpを作成し、次の内容にする。

(プロジェクト名)\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に次のルーティング処理を追記する。

web.php
Route::get('/form','FormController@getindex');
Route::post('/form','FormController@postindex');

ここで意図した設計で稼働しているか確認してみる。
http://127.0.0.1:8000/form にアクセス。

screenshot.jpg

この状態で送信を押すと、

screenshot.jpg

このように変化する。

Requestクラスの基本(3/5):初心者のためのLaravel入門 - libro 以降ではクエリやURLの取得、リダイレクトについて記載されているため、確認してみては。

データベースとの連携

ここではXAMPPMySQLを利用して、Laravelとデータベースを連携させる。

まずはデータベースの準備から。
XAMPPを起動したら、XAMPPのコントロールパネルにおけるMySQLAdminをクリックして、phpMyAdminに接続する。

screenshot.jpg

phpMyAdminにログインできたら、データベースタブから下記画像のように新規データベースを作成する。(画像ではデータベース名が頭文字が大文字だったが作成したら小文字になった。)
screenshot.jpg

そして、新規テーブルを作成する。
好きな名前とカラム数を設定してテーブルを作成し、
screenshot.jpg

各カラムの設定を行い、
screenshot.jpg

サンプルデータを何個か入れる。
screenshot.jpg

ここまで(↓)設定できたら、次はLaravel側の設定に移る。
screenshot.jpg

今回はMySQLを使用するが、他のデータベースを利用したい場合は、(プロジェクト名)\config\database.phpを開いて、下記の部分を使用したいデータベースに変える。

(プロジェクト名)\config\database.php
'default' => env('DB_CONNECTION', 'mysql'),

どのデータベースを使用するか設定できたら、(プロジェクト名)\.envを開いて、下記にデータベース情報を入力していく。
デフォルトで値が入っているが、必要があれば変更する。

(プロジェクト名).env
DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

ここからはデータベースに接続し、値を取得、ページに表示するまでを説明していく。

コントローラーの作成から行っていく。
(プロジェクト名)\app\Http\ControllersDatabaseController.phpを作成し、下記の内容にする。

(プロジェクト名)\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処理を実行した場合、UpdateDeleteが同時に実行する命令が起きるようなデータの不整合が起きる可能性がある。
そのような事態に陥るのを防ぐために行われるのが トランザクション で、DB::beginTransaction(); から DB::commit(); の間に書かれた処理が実行されている間は他の命令が実行されることを防ぐことができるようになる。
本番環境でデータの書き換えを行うような処理を定義する場合は忘れずに記述するようにしておく。

本題に戻って、コントローラーが取得したデータベースのデータを表示するページを作成していく。
(プロジェクト名)\resources\views\database.blade.phpを作成し、下記のような内容に。

(プロジェクト名)\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に今回のルーティング処理を実装して、実際にページを確認してみる。

(プロジェクト名)\routes\web.php
Route::get('/database','DatabaseController@getindex');

自分の今までに掲載した画像の設定と同じ設定にすれば次のように表示されるはず。
http://127.0.0.1:8000/database

screenshot.jpg

ORM(Object/Relational Mapping)について

さっきは自分でデータベースを作成して値を取得、表示まで行ったが、仕事でも同じような状況で作業ができるとは限らない。
違う人がデータベースを作成する事なんて普通だし、そもそもデータベースを見れずに手探りでデータを取得しなければならないことだってあり得る。
そのような状況で、今までのようなやり方では不都合が多い。

そこでPHPのようなオブジェクト指向言語で用いられる技術が ORM(Object/Relational Mapping) だ。
この技術を用いることで、データベースのテーブルに存在しているデータ、値をPHPのオブジェクトに変換したり、その逆の変換も行えるようになる。
その上、PHP側で用意したクラスを操作するだけで、それに対応するデータベースのテーブルを自動的に操作できるようになるという。

Laravelでは Eloquent というORMが利用できるため早速使用してみる。

最初にテーブルに対応するモデルと呼ばれるクラスの作成を行う。
ターミナルでプロジェクトのトップディレクトリに移動し、下記コマンドを実行。
自分はどのテーブルを扱うのかわかりやすいよう、テーブル: sampleに対し、モデル: Sampleを作成した。

 $ php artisan make:model Sample(モデル名)

上記のコマンドが成功すると、(プロジェクト名)\appSample(モデル名).phpが作成されているので、開いて確認してみると次のような内容になっている。

(プロジェクト名)\app\Sample(モデル名).php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Sample extends Model
{
    //
}

//とコメントアウトにされている箇所があるが、そこを protected $table = 'sample'; に変更して、使用するテーブル名を定義する。
protectedを付けることで、そのクラス自身と継承したクラス限定でアクセスが可能となるため、テーブルを保護するためにも欠かさずに付与する。
モデルの作成はこれで完了。コントローラーの作成に移る。

(プロジェクト名)\app\Http\ControllersORMController.phpを作成し、下記の内容を入力する。
データベースとの連携で使用した表示用のファイル(プロジェクト名)\resources\views\database.phpを使用するため、view()関数の第一引数はdatabaseにする。

(プロジェクト名)\app\Http\Controllers\ORMController.php
<?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にルーティング処理を実装し、実際にページを確認してみる。

web.php
Route::get('/orm','ORMController@getindex');

http://127.0.0.1:8000/orm にアクセスしてみて、http://127.0.0.1:8000/database と同じ内容が表示されているか確かめる。
screenshot.jpg

all の他にもデータベースにおける処理に関するメソッドがモデルクラスには用意されている。
その中の一つが検索機能の where だ。
whereモデル名::where(カラム名, 取得したい値) でテーブルに検索をかけて、 get() でその結果を取得する。
コントローラーに実装して、試してみるとそれぞれ次のようになる。

ORMController.php
class ORMController extends Controller
{
    public function getIndex(Request $request)
    {
        $data = Sample::where('id', 2)->get();
        return view('database', ['message' => 'データベース名: sample','data' => $data]);
    }
}
?>

screenshot.jpg

検索を実行できるwhereには様々な使い方がある。
>likeといった演算子を使いたい場合は where(カラム名, 演算子, 取得したい値)and条件なら where(条件1) -> where(条件2)or条件なら where(条件1) -> orWhere(条件2) という風になる。
データベースから値を取得する機会は多いので、少なくともこれらだけでも覚えておきたい。

Laravelからデータベースのデータを操作する

CRUD処理 において、Readに関してはORMwhereで触れたが、CreateUpdate,Deleteがまだなので、今回はそれらに触れていく。

前準備

ORMの際に作成したモデルに2つのコードを追加する。

(プロジェクト名)\app\Sample(モデル名).php
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を作成し、次のような内容に。

(プロジェクト名)\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を適用したいカラムを選択して、変更をクリック。
screenshot.jpg

その後、A_Iの下のチェックボックスにチェックを入れ、保存。
screenshot.jpg

もし、使用しない場合はIDの値を入力するフォームを作成を忘れないように。

postから投げられたデータはコントローラーでデータベースのテーブルに挿入する。
その処理は以下のような内容。

(プロジェクト名)\app\Http\Controllers\CreateController.php
<?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に下記のルーティング処理を実装し、実際にページを確認してみる。

(プロジェクト名)\routes\web.php
Route::get('/create','CreateController@getindex');
Route::post('/create','CreateController@postindex');

post
screenshot.jpg

post後(IDの5,6が抜けてるのは作成中にエラーの対応をしていたため)
screenshot.jpg

Update

表示用のページとして(プロジェクト名)\resources\views\update.blade.phpを作成し、form以下を次の内容に。
それ以外はCreateで作成したcreate.blade.phpと同じ。

(プロジェクト名)\resources\views\update.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と同じ。

(プロジェクト名)\app\Http\Controllers\UpdateController.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に下記のルーティング処理を実装し、実際にページを確認してみる。

(プロジェクト名)\routes\web.php
Route::get('/update','UpdateController@getindex');
Route::post('/update','UpdateController@postindex');

post前: http://127.0.0.1:8000/update?id=7
フォームの内容を変更したい内容に変えてある。
screenshot.jpg

post
screenshot.jpg

Delete

表示用のページとして(プロジェクト名)\resources\views\delete.blade.phpを作成し、formを次の内容に。
それ以外はCreateで作成したcreate.blade.phpと同じ。

(プロジェクト名)\resources\views\delete.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と同じ。

(プロジェクト名)\app\Http\Controllers\DeleteController.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に下記のルーティング処理を実装し、実際にページを確認してみる。

(プロジェクト名)\routes\web.php
Route::get('/delete','DeleteController@getindex');
Route::post('/delete','DeleteController@postindex');

post前: http://127.0.0.1:8000/delete
screenshot.jpg

post
screenshot.jpg

番外編: バリデーション

CRUD処理の番外編としてバリデーションにも触れていく。
この機能は入力内容をチェックし、設定した条件を満たしているかどうかを判断するもので実装する方法は複数あるが、今回はフォームのバリデーションを実装する。
フォームのバリデーションはLaravelにおいて、フォームリクエストと呼ばれる。
今回はUpdateで使用したファイル達に、このフォームリクエストを適用していく。

フォームリクエストは以下のコマンドをターミナルで実行して作成する。

$ php artisan make:request UpdateRequest(作成したいファイル名)

処理が完了すると(プロジェクト名)\app\Http\RequestsUpdateRequest(作成したいファイル名).phpが作成される。
UpdateRequest(作成したいファイル名).phpの各メソッドを次のように変更する。

(プロジェクト名)\app\Http\Requests\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に作成したバリデーションを適用させていく。

(プロジェクト名)\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も変更する。

(プロジェクト名)\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>

これでバリデーションが適用された際、どのフォームが条件を満たしていないかが赤字で表示されるようになった。
image.png

Laravelからテーブルを操作する

ここまででLaravel側からデータベースのテーブルに対する操作ができることを学んだが、Laravelではテーブルそのものを作成することもできる。

ここからはLaravel入門 - 使い方チュートリアル - - QiitaLaravel5 チュートリアル ブログもどきを作る(1) DB設定・マイグレーション - Qiitaシリーズを軸に進めていく。

マイグレーション

Laravelのテーブルそのものを作成する仕組み、それが マイグレーション だ。

まずはデータベースにテーブルを作成するためのマイグレーションファイルを作成するところから始まる。
今回はlaravelsというテーブル名で、それを作成するためのマイグレーションファイルを以下のコマンドをターミナルに入力して作成する。
テーブル名の最後にsを忘れないように

$ php artisan make:migration laravels(作成したいマイグレーションファイル名) --create=laravels(作成したいテーブル名)

そうすると、(プロジェクト名)\database\migrations2020_08_06_095118_laravels(作成したいマイグレーションファイル名).phpが作成される。

(プロジェクト名)\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() にはテーブルを削除する処理が記載されている。
このまま、このファイルを実行してもテーブルを作成してもよいが、次のように少しカラムの設定を宣言してみる。

(プロジェクト名)\database\migrations\2020_08_06_095118_laravels(作成したいマイグレーションファイル名).php
    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_atupdate_atのカラムは自動で作成され、AUTO_INCREMENTは自動挿入、timestampは日時が自動で挿入される機能。

では、このファイルを実行して、テーブルを作成してみる。

ターミナルに次のコマンドを入力することで、マイグレーションファイルが実行される。

$ php artisan migrate

phpMyAdminで確認してみる。
image.png

migrateでテーブルを作成するpublic function up()の処理が行われた。
public function down()の処理はmigrate:rollbackmigrate: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\seedsStudySeeder(作成したいシーディングファイル名).phpが作成される。

(プロジェクト名)\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で、この表の内容を入力できるようにするには次の内容にする。

(プロジェクト名)\database\seeds\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を実行するため、このファイルも編集する。

(プロジェクト名)\database\seeds\DatabaseSeeder.php
public function run()
    {
        $this->call(StudySeeder::class);
    }

StudySeederの部分を各自のシーディングファイル名に変更。

以上で設定は終わりなのでシーディングを実行してみる。
シーディングの実行はターミナルで次のコマンドを叩く。

$ php artisan db:seed

phpMyAdminを確認してみる。
image.png

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) 認証機能の有効化編

参考資料

8
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
16