---
# System prepended metadata

title: Laravel 01

---

# 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
その他は設定不要
:::
![](https://i.imgur.com/FyERMXQ.png)


#### ② 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 の順で処理が実行される．

![](https://i.imgur.com/4XmQdQn.png)
©︎taroosg


DB から取り出したデータの流れ
Model -> Controller -> View の順で処理が実行される．
![](https://i.imgur.com/tIWOZwn.png)
©︎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テーブルとカラムが作成されているか確認しましょう
![](https://i.imgur.com/ch1Slxh.png)



## ② Modelを作成（テーブルを簡単に扱えるようにする機能）

Modelはデータベースをうまく処理してくれる役割を担います。
①で作った`booksテーブル`に対応する`Bookモデル`をここでは作成しましょう。

![](https://i.imgur.com/dxSRof8.png)
©︎山崎学校長

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を作成（登録&表示のためのページ）
ここでは実際に表示画面を作成していきましょう
![](https://i.imgur.com/kVDn3qc.png)
©︎山崎学校長

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を作成していきましょう
![](https://i.imgur.com/v58AZRA.png)
©︎山崎学校長

:::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
![](https://i.imgur.com/22UFzC5.png)



## ⑤ 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で確認
![](https://i.imgur.com/pDEYukg.png)


## ⑥ 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>&nbsp;</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. プレビュー画面で、一覧表示できているか確認
![](https://i.imgur.com/s23MHGV.png)


:::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('/');
});
```
