Laravel 〜Laravelアプリ作成の流れ〜AWS Cloud9

# Laravelアプリ作成の流れ
今回は[Laravel 6.x](https://readouble.com/laravel/) を使用

## 環境構築
AWS Cloud9を使用する。
無料枠であれば以下の様にすると良い。
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/5cbfbc13-c686-c6f5-3b27-4a249f8898a3.png' width='500'>

## Laravelインストール
[インストール](https://readouble.com/laravel/6.x/ja/installation.html)

```terminal

# phpの設定を行う(yesかnoが表示されたら基本yes)
sudo amazon-linux-extras install php7.2=stable

sudo yum install php-cli php-common php-devel php-fpm php-gd php-mysqlnd php-mbstring php-pdo php-xml


# MariaDBの構築（MariaDBはMySQLの新しい版のようなもの）
sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2

# MariaDBのインストール
sudo yum install -y mariadb-server


#Apache, MariaDBの起動対応
sudo systemctl start mariadb

sudo mysql_secure_installation
// Enter current password for root (enter for none): 
// 上記は空欄でそのままEnterでOK
// Set root password? [Y/n] 
// 上記以降はyで回答すればOK（パスワードは任意：ここではrootにしている)

#MaridaDBの自動起動を有効化する
sudo systemctl enable mariadb

sudo systemctl is-enabled mariadb

# Composerをインストール

curl -sS https://getcomposer.org/installer | php

sudo mv composer.phar /usr/bin/composer

composer

// 上記は３つの記述をまとめて記述（貼り付けをして実行可能。成功するとComposerの文字がターミナル上に表示される）
```
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/757e11d8-77c8-f98d-b473-a1a983154019.png' width='300'>

```terminal
# Laravelをインストール
composer create-project laravel/laravel cms 6.* --prefer-dist

# cd cms
// cmsディレクトリへ移動する。このディレクトリにartisanがある。
// その為、artisanコマンドはこの階層で実行する。

# Composerコマンド実行する
sudo composer update

# サーバー起動
php artisan serve --port=8080
```
![スクリーンショット 2022-05-28 18.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/e389578f-c616-0c20-c5a3-15b551fd2eb1.png)

**サーバーが起動したら、cloud9の上記画像の画面右上の歯車の左下の斜め矢印を押し、別タブで画面を確認すると良い**
Previewの[Preview Running Application]を選択
```/resouces/views/welcome.blade.php``` を編集するとこの表示ページが編集できる。
ブラウザ・更新出来るか確認してみると良い。　

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/bd7020b0-809e-9610-cef5-1d994cfb44d0.png' width='300'>

今回はLaravelの横に「6」を追記してみた

```php
 <div class="title m-b-md">
    Laravel 6
</div>
```


### 自動Save設定
![スクリーンショット 2022-05-28 18.09.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/eb3de9d3-b6d8-cb39-1697-24f8115c94a0.png)
cloud9の右上の歯車を押して上記画面の場所でAfter Delayを選択するとコードが自動で保存される様になる。

### .envの設定

.envは隠しファイルの為、初期では表示されない。
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/853213a0-3961-6b37-ad41-207aa0a9a2e8.png' width='300'>
上記から「Show hidden files」を選択し、選択する。

```/cms/.env```を編集する

ここにDB周りの設定を記入する
初期状態は以下
```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel 
DB_USERNAME=root
DB_PASSWORD=
```
これを自身の環境に合わせて設定する。

```
# 例）
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=hogedb // 任意で設定
DB_USERNAME=root
DB_PASSWORD=root
````

### DB作成
```
//mysqlログイン
mysql -u root -p　

// pass入力
root

// db名は任意
create database hoge_db;
```
※DBについて
AmazonLinux2で環境を作った場合、MariaDBは自動で起動する為、毎回DBを起動する必要はない。
AmazonLinux AMI（旧AmazonLinux1）の場合は毎回CLOUD9起動時に必要。

```
// db選択
use hoge_db;

// テーブル確認
show tables;

// テーブル内容確認
desc tabale名;
```


## テーブル作成
**今回はbooksテーブルを作成する**
テーブルの作成は[マイグレーション](https://readouble.com/laravel/6.x/ja/migrations.html)を使用

テーブル作成の方法は
* 手順１ : ```php artisan make:migration create_〇〇s_table```を実行
この記述によって、テーブルを作るための記述を行うファイルが作成される。
ファイル生成場所：```/cms/database/migrations/2022_05_28_032210_create_books_table.php```
**マイグレーションファイルの作成**

```terminal
$ php artisan make:migration create_books_table
$ php artisan make:migration create_books_table --create=books
```
上記はどちらも同じ結果になる。
```--create=books```は生成されたファイル内で作成するテーブル名を指定している
基本ファイル名と生成するテーブル名は同じにする方が管理しやすい為、ここの名前を分ける事はしなくて良いと思う。
NG_例)
```php artisan make:migration create_books1_table --create=books2```
※ファイル名は「2022_05_28_035104_create_books1_table」なのにmigrationして作成されるテーブル名は「books2」テーブルとなる。

「create_○○○_table」は生成されるマイグレーションファイル名の一部。
○○○の部分には作成するテーブル名を指定する。

**作成されるファイル
```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()　//　migrateで実行される
    {
        Schema::create('books', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('item_name'); // 元々は無い記述（item_nameカラムをstring型で追加）
            $table->integer('item_number'); // 同上
            $table->integer('item_amount');// 同上
            $table->datetime('published');// 同上
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()　// rollbackで実行される
    {
        Schema::dropIfExists('books');
    }
}
```


* 手順2 : ```php artisan migrate```
この記述によって「手順1」で作成したファイルの情報を元にDBのテーブルが作成される。

### マイグレーションを戻したい時
作成したテーブルを削除したい時は```php artisan migrate:rollback```を使用する。
[参考記事](https://readouble.com/laravel/6.x/ja/migrations.html#:~:text=%E6%88%BB%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,php%20artisan%20migrate%3Arollback,-rollback%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AB)

## モデルの設定
モデルの定義は[Eloquent ORM](https://readouble.com/laravel/6.x/ja/eloquent.html?header=%25E3%2582%25A4%25E3%2583%2599%25E3%2583%25B3%25E3%2583%2588)を使用。

Lravelの命名ルールに則して、テーブル名に対応した名前をつける（**今回はBook**)
**※1. モデル名は頭文字を大文字にする**
　**2. 末尾に「s」はつけない**
　（命名ルールを使用しないでどのテーブルと紐付かせるか任意で設定も可能）

**生成されるファイル**
```php artisan make:model Book```を実行する。
ファイル生成場所：```/cms/app/Book.php```

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    //
}
```

### その他のモデル設定方法
```php artisan make:model Flight --migration```
上記を実行すると
* モデル用の/cms/app/Flight.php
* テーブルマイグレーション用の/cms/database/migrations/2022_05_28_042514_create_flights_table.php
が一度に生成出来る。


## ルート定義
[基本的なルーティング](https://readouble.com/laravel/6.x/ja/routing.html)は```/cms/routes/web.php```に記載する。

↓初期のweb.phpの表記は以下
```php
Route::get('/', function () {
    return view('welcome');
});
```

↓CRUDを意識した記載例は以下
```php
use App\Book; // app/Book.phpを参照
use llluminate\Http\Request; // HTTPリクエストを扱う為等のメソッドを参照


// 本の一覧表示（books.blade.php)
Route::get('/', function () {
    return view('welcome');
});



// 本を追加
Route::post('/books', function (Request $request) {
        
});

// 本を削除
Route::delete('/book/{book}', function (Book $book) {
    
});```

### use を使用し参照する2つのクラスについて
```use llluminate\Http\Request;```については[こちらを参照する](https://readouble.com/laravel/6.x/ja/requests.html)



## ログイン認証機能
Laravelでは標準でログイン機能とユーザー登録機能がある。
[参考ドキュメント](https://laravel.com/docs/6.x/frontend#introduction)

```
# laravel/uiパッケージをインストール
composer require laravel/ui:^1.0 --dev

# artisanコマンド実行
php artisan ui vue --auth


# npmパッケージインストール
npm install

# パッケージをビルド
npm run dev

## ビュー
[テンプレートの継承](https://readouble.com/laravel/6.x/ja/blade.html)
[ビューの作成](https://readouble.com/laravel/6.x/ja/views.html)

### ファイルの場所
基本は```/cms/resources/views/```以下に設置する。
Laravelでは親（ベース）/子(パーツ）テンプレートという、テンプレートを効率よく管理・作成する方法が用意されている。
**※ベーステンプレートは最初からあるわけではない**
laravel/uiパッケージをインストールすると、その際、自動で作成される。
#### ベーステンプレートの場所
```/cms/resources/views/layouts/app.blade.php```

app.blade.phpがベーステンプレートになる
この場合、パーツテンプレートが
```/cms/resources/views/welcome.blade.php```になる。

### 読み込みの考え方
コントローラーの「routes/web.php」で呼び出される際は、
1. 「/cms/resources/views/welcome.blade.php」が読み込まれ
1. 1の中の「/cms/resources/views/layouts/app.blade.php」が呼び出される

### @yield('content') : ベーステンプレート
ベーステンプレートに記載の```@yield('content')```の部分にパーツテンプレートの```@selection('content')```と```@endsection```の記述を読み込ませる事が出来る。
**※contentの部分は変更可能**

#### @extends('layouts.app')
パーツテンプレートに記載の```@extends('layouts.app')```は「.」が「/」と解釈され、**layouts/app**.blade.phpを読み込むという意味となる。

#### @includeディレクティブ
```@include(ディレクトリ名.ファイル名)```で記述した箇所にファイルを読み込む

### 変数の使い方
* Bladeテンプレートでは
```{{$hoge}}```のようにエスケープつけて変数を記述する。
XSS攻撃対策が上記ではなされる

* なされない記述もある
```{!!$hoge!!}```
基本これは使わない。

* ```{{$hoge or "デフォルト"}}```この記述では変数hogeが定義されていれば変数を、そうでなければ「デフォルト」という文字を表示する様になる記述


## JavascriptとCSSのファイルの場所はpublicフォルダ
読み込みには**asset()関数**を使用する。
asset()関数はpublic以下を参照する。

例）public以下にassetsフォルダを作成した場合

```php
<script src="{{assets('/assets/js/jquery.min.js')}}"></script>
```

#### assets()関数の第2引数にtrueを渡すと「https://」が付く。
※設定しない場合はfalseとなり、「http://」となる
```php
<script src="{{assets('/assets/js/jquery.min.js',true)}}"></script>
```


## バリデーション
[参考](https://laravel.com/docs/6.x/validation#available-validation-rules)
基本はroute/web.phpに記入していく

```php
* 本を追加 
*/
Route::post('/books', function (Request $request) {
    
    // バリデーション 
    $validator = Validator::make($request->all(),[
        'item_name'=>'required|max:255',
        ]);
        
    // バリデーションエラー
    if ($validator->fails()) {
        return redirect('/')
        ->withInput()
        ->withErrors($validator);
    };
});
```

#### withInput()
フォームの入力値をセッションへフラッシュデータとして保持する。

例）
```php
<input name="name名" value="{{old('name属性値')}}" >
```
とする事で、バリデーションエラーとなり、リダイレクトされた先のページでもそのエラー時のデータを保持し、表示する事が可能になる。

#### withErrors()
バリデーションのエラー内容をフラッシュデータとしてセッションへ保存し、どのテンプレートからでも$errors変数としてアクセスできる様にする。

これにより、errors.blade.phpを用意し

```php
<!-- resources/views/common/errors.blade.php -->
@if (count($errors) > 0)
    <!-- Form Error List -->
    <div class="alert alert-danger">
        <div><strong>入力した文字の修正が必要です。</strong></div> 
        <div>
            <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
            </ul>
        </div>
    </div>
@endif
```
上記の様に設定する事で、エラー時の処理が作れる。