# Laravel 01
## 今日のコンテンツ
* 環境構築
* ターミナル操作
* MVCモデル
* CRUD実装
* ログイン認証
※授業では下記の順番で学習します
1. ターミナル操作 & 環境構築
2. ログイン認証
3. MVCモデル学習
4. CRUD実装
## 今日の目標
* MVCモデルがどういうものか感覚をつかむ
* Laravelの操作になれる
* Laravel Loveになる
---
## 環境構築
この章ではPaiza Cloudでサーバーを立てて、Laravelプロジェクトを作成、DBの作成と接続、そのほかの初期設定を行います
:::success
① Paiza Cloudでサーバー作成
② Laravelプロジェクトの作成
③ データベース作成&接続
④ /app/Providers/AppServiceProvider.php ファイルを修正
:::
#### ① Paiza Cloudでサーバー作成
1. アカウント取得
https://paiza.cloud/ja/
※ ライトプランのクーポンで作成済み
Paiza Cloudでデプロイまで行いたい場合は別途ベーシックプランが必要
2. サーバーの作成
* 「新規サーバー作成」をクリック
* 下記設定で、「新規サーバー作成」
:::info
サーバ名:デフォルトでOK
web開発:PHP,Laravel
データベース:MySQL,phpMyAdmin
その他は設定不要
:::

#### ② Laravelプロジェクトの作成
1. ターミナル上でLaravelプロジェクト作成コマンドを入力
`composer create-project laravel/laravel cms 6.* --prefer-dist`
:::info
【メモ / `cms`が今回作るプロジェクトのディレクトリ名】
>「CMS」とは、「Contents Management System:コンテンツ・マネジメント・システム」の略で、簡単にいうとWebサイトのコンテンツを構成するテキストや画像、デザイン・レイアウト情報(テンプレート)などを一元的に保存・管理するシステムのこと
> https://www.hitachi-solutions.co.jp/digitalmarketing/sp/column/cms_vol01/
:::
:::info
【メモ / 授業で使うバージョン】
```
PHP 7.4.1
Laravel 6 (LTS)
```
ググる時はそのサイトがどのバージョンについて書かれているかも気にしてみましょう
:::
2. プロジェクトディレクトリに移動
```
cd cms
```
3. Composerコマンドを実行
```
sudo composer update
```
4. BuiltInのLaravelサーバーを起動
```
php artisan serve
```
5. 動作確認
ターミナルで下記の実行結果が表示されていればOK。
```
Starting Laravel development server: http://127.0.0.1:8000
```
ブラウザ(8000番ポート)をクリックして、実際にプレビュー画面を表示してみましょう(Laravelのホーム画面が表示されていれば成功!)
#### ③ データベース作成&接続
1. データベースを作成
方法はいくつかありますが、今回はターミナルで作成にチャレンジしてみましょう!
* ターミナルでDB作成する場合
ターミナル上で下記の手順で実行
```
mysql -u root -p
root [Enterキー]
create database c9;
exit;
```
* phpMyAdminで作成する場合
①左タブからphpMyAdminのタブ内「Open phpMyAdmin」をクリック
②phpMyAdminの管理画面で `c9` というDBを作成
※照合順は`utf8mb4_general_ci`を選択
2. 隠しファイルを表示
エディタ左側のファイル階層で右クリック→「隠しファイルを表示」
3. .envファイルを編集
cms直下にあるenvファイル内の同じファイルを上書き
```
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=c9
DB_USERNAME=root
DB_PASSWORD=
```
:::info
【メモ】envはenvironment(環境)の略
:::
4. Webサーバーを再起動
:::danger
超重要!!!**`.env`を変更後はWebサーバーを再起動**する
:::
i. 起動中のwebサーバーを停止
`Ctl + C`
ii. cmsディレクトリにいることを確認後、サーバー起動
`php artisan serve`
#### ④ Laravelの/app/Providers/AppServiceProvider.php ファイルを修正
```php
use Illuminate\Support\Facades\URL; //この行を追加
public function boot() {
URL::forceScheme('https'); //この行を追加
}
```
:::info
【Paiza Cloudのポイント】
ファイルを開いた時は「自動保存」にチェック
または 必ず `Ctl + S` (windows) / `Command + S` (mac)を!
:::
---
## ターミナル操作
```
# LiSt ディレクトリ一覧を表示
ls
```
```
# Change Directory ディレクトリを変更
cd + ディレクトリ名
# 一つ戻る場合は
cd ../
```
```
# Print Working Directory 現ディレクトリを表示
pwd
```
```
# ターミナルの画面をリセット
clear
```
```
# 実行中のコマンドを強制終了
Ctl + C
```
---
## ログイン認証
この章ではログイン認証を実装して、Laravelの凄さを体験してみましょう!
1. マイグレーションを実行
```
php artisan migrate
```
2. laravel/ui パッケージをインストール
```
composer require laravel/ui:^1.0 --dev
```
※Laravel UIは認証周りの機能の雛型を生成してくれるLaravel公式のライブラリ
3. artisan コマンドを実行
```
php artisan ui vue --auth
```
4. npmパッケージをインストール
```
npm install
```
5. パッケージをビルド
```
npm run dev
```
---
## MVCモデル
この章では、Webフレームワークの設計モデル(アーキテクチャ)の一つであるMVCモデルを学びましょう
Model,View,Controllerそれぞれの役割を理解することで、Laravelでのアプリ開発がよりスムーズになります
:::info
【解説 / MVC】
MVCとは,役割分担の概念!
これまでは適当な PHP ファイルに処理を全部書いていた!
ファイル数が増える...
あの処理,どのファイルに書いたっけ..??
バグあったけど次の処理が他の人の書いたファイルに...(チーム開発)
=> いずれ詰む未来が見える...
=> せや,処理毎に別々のところに書いて管理や分類をしやすくしたろ!MVC の 3 つくらいでええやろ!
引用元:taroosg先生
:::
| 役割 | 解説 |
| -------- | -------- |
| Model | データ処理全般を担当。データーベースアクセスに関する処理全般を行う|
| View | 画面表示を担当。表示に使うテンプレート(blade)などがこれに相当 |
| Controller| 全体の制御を担当。司令官。場合によってModelやViewに指示を出す|
| Routing | 特定のアドレスにアクセスしたときに、どの処理を呼び出して実行するのか担当。URLとControllerのどの処理を行うのか紐付ける|
例として,DB から取り出したデータを一覧画面に表示する流れを考えてみる.
リクエストからの処理の流れ
リクエスト -> Route -> Controller の順で処理が実行される.

©︎taroosg
DB から取り出したデータの流れ
Model -> Controller -> View の順で処理が実行される.

©︎taroosg
---
## ブックマークアプリの実装
この章ではいよいよ本格的にブックマークアプリのCRUD処理を開発します
どういう役割のコードを書いているのか、感覚をつかみながら開発しましょう
:::success
① DBのテーブルを作成 (マイグレーションファイルの作成と実行)
② Modelを作成(テーブルを簡単に扱えるようにする機能)
③ Viewを作成(app.blade.php & books.blade.php)
④ ルート定義(ルーティング)を作成
⑤ CRUD機能実装(登録)
⑥ CRUD機能実装(表示)
⑦ CRUD機能実装(削除)
⑧ CRUD機能実装(更新)
:::
## ① DBのテーブルを作成 (マイグレーションファイルの作成と実行)
ここでは、本を登録するためのBDテーブルを作成します
LaravelではMigrationというテーブル作成に便利な機能が備わっています
```
【解説 / マイグレーション】
マイグレーションとは「マイグレーションファイル」を用いてテーブルを管理する仕組み
「マイグレーションファイル」にテーブル名やカラム名を記述し,指定されたコマンドを実行することで設定したテーブルが生成される
```
1. booksテーブルの設計書(マイグレーションファイル)を作成
```
php artisan make:migration create_books_table --create=books
```
※成功すると、database/migrationsの直下にbooks_table.phpが作成されます
2. database/migrationsの直下のbooks_table.phpに以下追記
```php
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('item_name'); //追加
$table->integer('item_number'); //追加
$table->integer('item_amount'); //追加
$table->date('published'); //追加
$table->timestamps();
});
}
```
3. マイグレーション(テーブル作成)を実行
ターミナル上でコマンド実行
```
php artisan migrate
```
4. booksテーブルが作成されているか確認
実行したら、phpMyAdminでbooksテーブルとカラムが作成されているか確認しましょう

## ② Modelを作成(テーブルを簡単に扱えるようにする機能)
Modelはデータベースをうまく処理してくれる役割を担います。
①で作った`booksテーブル`に対応する`Bookモデル`をここでは作成しましょう。

©︎山崎学校長
1. ターミナルでコマンドを実行
```
php artisan make:model Book
```
2. /app/Book.php に作成されたことを確認
:::info
【解説 / Eloquent Model】
Eloquent Model は Laravel 標準の ORM(object-relational mapper)である.
ORM とは,DB のレコードをオブジェクトとして直感的に扱えるようにしたもので,SQL を意識せずにプログラムで処理を記述することができる.
Eloquent Model は定義された「Model」を用いることで簡単に DB へのデータ保存・取得などを行える.
1 つのモデルが 1 つのテーブルに対応する.例えば,booksテーブルに対してBookのようにモデルを定義すると自動的に対応する.モデル内に明示的に対応を記述することもできる.
テーブルに対してデータ操作を行う場合,対応するモデルに対して処理を実行することで DB 操作を行うことができる.
引用元:taroosg先生
:::
:::info
【+α】
①のMigrationファイルと②のModelは同時に作成することができる
-m のオプションを末尾につける
例)php artisan make:model Book -m
他にもControllerを同時に作れたりと、色々なオプションが用意されているので、慣れてきたら利用しましょう
:::
> 参考:https://qiita.com/niisan-tokyo/items/9c799989cb535489f201
## ③ Viewを作成(登録&表示のためのページ)
ここでは実際に表示画面を作成していきましょう

©︎山崎学校長
1. /resources/views/layouts/app.blade.php を作成
app.blade.phpを未作成の場合、以下コードを貼り付けます。
:::danger
*※今回はログイン認証をlaravel/uiを利用して作成した際にapp.blade.phpを自動で作成済みなので、このステップは行いません*
:::
```htmlmixed
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Book List</title>
<!-- CSS と JavaScript -->
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
<!-- ナビバーの内容 -->
</nav>
</div>
@yield('content')
</body>
</html>
```
2. /resources/views/books.blade.php を作成
以下コードを貼り付けます
```htmlmixed
@extends('layouts.app')
@section('content')
<!-- Bootstrapの定形コード… -->
<div class="card-body">
<div class="card-title">
ブックマーク
</div>
<!-- ↓バリデーションエラーの表示に使用-->
<!-- ↑バリデーションエラーの表示に使用-->
<!-- 本登録フォーム -->
<form action="{{ url('books') }}" method="POST" class="form-horizontal">
@csrf
<!-- 本のタイトル -->
<div class="form-group col-md-6">
<label for="item_name" class="col-sm-3 control-label">タイトル</label>
<input type="text" name="item_name" class="form-control" id="item_name">
</div>
<!-- 本 登録ボタン -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary">
Save
</button>
</div>
</div>
</form>
</div>
<!-- Book: 既に登録されてる本のリスト -->
@endsection
```
:::danger
【重要 / form actionは@csrfと一緒に使う】
クロス・サイト・リクエスト・フォージェリは悪意のあるエクスプロイトの一種
`@csrf`はその攻撃から守ってくれる
※ `{{ csrf_field()}}`も同じ意味
:::
:::info
【コード解説 / @yieldと@sectionの部分は何している?】
親のapp.blade.php `@yield('content')`のところに、
子のbooks.blade.php `@secion('conten')` ~ `@endsection`までの部分を挿入している
:::
## ④ ルーティング
これまでにDB+Model(データの操作を担当)、View(表示を担当)を作成しました
ここでは、Webアプリの玄関口(受付)となるRoutingを作成していきましょう

©︎山崎学校長
:::info
【解説 / ルーティング】
アクセスしたアドレスを元に処理を割り振るための機能
:::
1. /routes/web.phpに以下の記述を追加
先頭部
```php
use App\Book;
use Illuminate\Http\Request;
```
中間
```php
// 本のダッシュボード表示(books.blade.php)
Route::get('/', function () {
return view('books'); //** ここを修正 **
});
// ** ここから追加 **
// 新「本」を追加
Route::post('/books', function (Request $request) {
//
});
// 本を削除
Route::delete('/book/{book}', function (Book $book) {
//
});
```
2. プレビュー画面で確認
無事に本のタイトルを入力するフォームが表示されていればOK

## ⑤ CRUD機能実装(登録)
1. /routes/web.phpを編集
```php
// 新「本」を追加
Route::post('/books', function (Request $request) {
$books = new Book;
$books->item_name = $request->item_name;
$books->item_number = '1'; // 今は固定値で登録
$books->item_amount = '1000'; //今は固定値で登録
$books->published = '2017-03-07 00:00:00'; //今は固定値で登録
$books->save();
return redirect('/');
});
```
2. formを送信した後にDBに登録処理ができているか、phpMyAdminで確認

## ⑥ CRUD機能実装(表示)
ここでは、登録したデータの一覧を取得し表示する機能を実装していきましょう
1. /routes/web.phpを編集
```php
Route::get('/', function () {
$books = Book::orderBy('created_at', 'asc')->get();
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
});
```
2. /resources/views/books.blade.php
< !-- Book: 既に登録されてる本のリスト -->の下に追加
```htmlmixed
<!-- 現在の本 -->
@if (count($books) > 0)
<div class="card-body">
<table class="table table-striped task-table">
<!-- テーブルヘッダ -->
<thead>
<th>本一覧</th>
<th> </th>
</thead>
<!-- テーブル本体 -->
<tbody>
@foreach ($books as $book)
<tr>
<!-- 本タイトル -->
<td class="table-text">
<div>{{ $book->item_name }}</div>
</td>
<!-- 本: 削除ボタン -->
<td>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
```
3. プレビュー画面で、一覧表示できているか確認

:::info
【解説 / @foreach】
Bladeテンプレートエンジンに備わっている便利な繰り返し処理をしてくれる機能
PHPの `foreach` と同じ感じで書ける
:::
:::info
【+α / `$books`に値が入っているかのデバッグ】
viewで`$books`に値が入っているか確かめたい時は
`{{ddd($books)}}`
を仕込んでみよう
※Controllerで `ddd($books);` をするのもGOOD
:::
:::success
Laravel01_授業はここまでです。おつかれ様でした!
【Special Thanks】
:clap: 山崎学校長
:clap: taroosg先生
:clap: 中野先生
:::
---
※Laravel02授業はCRUDの続きから行います
## ⑦ CRUD機能実装(削除)
1. books.blade.phpに削除ボタンを追加
< !-- 本: 削除ボタン -->下の<td></td>要素内に追加
```htmlmixed
<form action="{{ url('book/'.$book->id) }}" method="POST">
@csrf
@method('delete')
<button type="submit" class="btn btn-danger">
削除
</button>
</form>
```
:::info
【解説】
削除ボタンクリック時には,コントローラのdestroy()関数にリクエストが送られる.
削除の処理を行うにはDELETEメソッドでリクエストを送る必要があるが,form からは GET または POST でしか送れない.
`@method('delete')`を記述することで,DELETEメソッドで送信できる.
※`{{ method_field('delete') }}` も同じ意味
:::
2. web.phpに「本を削除」のルート定義を追加編集
```php
Route::delete('/book/{book}', function (Book $book) {
$book->delete(); //追加
return redirect('/'); //追加
});
```
## ⑧ CRUD機能実装(更新)
1. books.blade.phpに更新ボタンを追加
削除ボタンの<td></td>タグの下
```htmlmixed
<!-- 本: 更新ボタン -->
<td>
<a href="{{ url('booksedit/'.$book->id) }}">
<button type="submit" class="btn btn-primary">更新</button>
</a>
</td>
```
2. booksedit.blade.phpをview配下に新規作成し、以下コードを貼り付け
```htmlmixed
@extends('layouts.app')
@section('content')
<div class="row container">
<div class="col-md-12">
<!-- ↓バリデーションエラーの表示に使用-->
<!-- ↑バリデーションエラーの表示に使用-->
<form action="{{ url('books/update') }}" method="POST">
<!-- item_name -->
<div class="form-group">
<label for="item_name">本のタイトル</label>
<input type="text" name="item_name" class="form-control" id="item_name" value="{{$book->item_name}}">
</div>
<!--/ item_name -->
<!-- Save ボタン/Back ボタン -->
<div class="well well-sm">
<button type="submit" class="btn btn-primary">Save</button>
<a class="btn btn-link pull-right" href="{{ url('/') }}"> Back</a>
</div>
<!--/ Save ボタン/Back ボタン -->
<!-- id 値を送信 -->
<input type="hidden" name="id" value="{{$book->id}}" /> <!--/ id 値を送信 -->
<!-- CSRF -->
@csrf
<!--/ CSRF -->
</form>
</div>
</div>
@endsection
```
3. [routing] web.phpに更新画面表示と更新処理を追加
```php
//「本」の更新画面表示
Route::get('/booksedit/{book}',function(Book $book){
return view('booksedit', ['book' => $book]);
});
//「本」の更新処理
Route::post('books/update',function(Request $request){
// Eloquent モデル
$books = Book::find($request->id);
$books->item_name = $request->item_name;
$books->item_number = '1'; // 固定値
$books->item_amount = '1000'; // 固定値
$books->published = '2017-03-07 00:00:00'; // 固定値
$books->save();
return redirect('/');
});
```