# Laravel授業1回目(Laravel9版)
## 授業資料
[ダウンロードリンク](https://drive.google.com/drive/u/0/folders/1-tcm0fWYLFEx5kFrHt0rwLYLlvg_PGOH)
## 環境構築
### 【PHPセットアップ】
#### 1.パッケージのアップデート
`sudo yum update -y`
#### 2.PHPのパッケージをすべてアンインストール
`sudo yum -y remove php-*`
#### 3.amazon-linux-extrasをアップデート
`sudo yum update -y amazon-linux-extras`
#### 4.amazon-linux-extrasで使用中のパッケージと使えるパッケージを確認
`amazon-linux-extras`
#### 5.lamp-mariadb10.2-php7.2を使用停止
`sudo amazon-linux-extras disable lamp-mariadb10.2-php7.2`
#### 6.PHP8.0を有効化
`sudo amazon-linux-extras enable php8.0`
#### 7-1.インストールするパッケージの案内があったので、表示されたコマンドを実行
`sudo yum clean metadata && sudo yum install php-cli php-pdo php-fpm php-mysqlnd`
#### 7-2.インストールするパッケージの案内があったので、表示されたコマンドを実行
`sudo yum install php-cli php-common php-devel php-fpm php-gd php-mysqlnd php-mbstring php-pdo php-xml`
#### 8-1.apacheなどを再起動
`sudo systemctl restart httpd.service`
#### 8-2.apacheなどを再起動
`sudo systemctl restart php-fpm.service`
### 【データベースの準備】
#### 1.MariaDBデフォルト確認
`sudo yum list installed | grep mariadb`
#### 2.MariaDBのインストール
`sudo amazon-linux-extras install mariadb10.5 -y`
#### 3.Apache, MariaDBの起動
`sudo systemctl start mariadb`
`sudo mysql_secure_installation`
```
初回設定の入力項目
Enter current password for root (enter for none): [Enterキー]
Switch to unix_socket authentication [Y/n] y
Set root password? [Y/n] y
New password: root
Re-enter new password: root
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y
```
#### 4-1.MaridaDBの自動起動を有効化
`sudo systemctl enable mariadb`
#### 4-2.MaridaDBの自動起動を有効化
`sudo systemctl is-enabled mariadb`
#### 5-1. Composerインストール(バージョン指定)
`curl -sS https://getcomposer.org/installer | php -- --version=2.3.5`
#### 5-2. Composerインストール
`sudo mv composer.phar /usr/bin/composer`
#### 5-3. Composerインストール
`composer`
#### 6. Laravelインストール(旧バージョン指定)
`composer create-project "laravel/laravel=9.1.8" cms`
#### 7. サーバーの起動とLaravelプロジェクトの起動チェック
#ディレクトリ移動
`cd cms`
#BuiltInサーバーを起動:動作確認
`php artisan serve --port=8080`
*Cloud9の画面上部の緑の起動ボタンの左側Previewボタン>Preview Running Applicationをクリック
右下に画面が起動してLaravelの文字が確認できたらOK (編集済み)
### 【データベースの作成】
`mysql -u root -p`
`root [Enterキー]`
`create database c9;`
`show databases; `
`exit;`
### 【Laravelプロジェクト初期設定】
#### 1. env(ファイル内の同じ箇所を上書き)
```
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=c9
DB_USERNAME=root
DB_PASSWORD=root
```
#### 2. サーバーの再起動
サーバー起動後のターミナル上で
`Ctrl + C`
#### 3. /app/Providers/ AppServiceProvider.php ファイルを修正
```
use Illuminate\Routing\UrlGenerator;//この行を追加
//bootメソッドを以下に変更
public function boot(UrlGenerator $url)
{
$url->forceScheme('https');
}
```
#### 4. 表示の仕組みをチェックしてみる!
#4-1 /resouces/views/welcome.blade.php を編集して見よう!
#4-2 ブラウザ・更新で確認 → 変更確認できればOK
### 【phpMyAdmin設定】
#### 1. cms階層からpublicフォルダに移動
`cd public`
#### 2. phpMyAdminのzipをダウンロード
`wget https://files.phpmyadmin.net/phpMyAdmin/5.1.2/phpMyAdmin-5.1.2-all-languages.zip`
#### 3. zipファイルを解凍
`unzip phpMyAdmin-5.1.2-all-languages.zip`
#### 4. cms階層に戻る
`cd ..`
> <手順解説>
> 1 publicフォルダ内に「phpMyAdmin-5.1.2-all-languages」フォルダが作成される
> 2 フォルダ名が長いので「phpMyAdmin」に変更
> 3「Preview」でサイトを開き、URLの最後に「phpMyAdmin/index.php」をつけてEnterキーを押す
> 4 URL例: https://******.cloud9.us-east-1.amazonaws.com/phpMyAdmin/index.php
> 5 phpMyAdmin画面が表示されたら: ユーザー名・パスワードともに「root」を入力してログイン
> 6 ログインできればOK
## ログイン認証
### 【ログイン認証実装】
#### 1. マイグレーションを実行
`php artisan migrate`
#### 2. laravel/ui パッケージをインストール(Laravel 9.x の場合)
`composer require laravel/ui`
#### 3. artisan コマンドを実行
`php artisan ui vue --auth`
#### 4. npmパッケージをインストール
`npm install`
#### 5. パッケージをビルド(1回目)
`npm run dev`
#### 6. パッケージをビルド(2回目)
`npm run dev`
*なぜかビルド2回必要です!
## 本管理アプリ実装(簡単なCRUDの実装)
### 【データベースにbooksテーブルを作成する為にマイグレーション を作成】
#### 1. artisanコマンドでマイグレーション 作成
`php artisan make:migration create_books_table --create=books`
#### 2. database/migrationsの直下のbooks_table.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->datetime('published');
$table->timestamps();
});
}
```
#### 3. マイグレーション実行(テーブルの作成)
`php artisan migrate`
### 【モデルの作成】
artisanコマンドでモデル作成
`php artisan make:model Book`
#### 2./routes/web.phpに以下二行を追記してモデルを呼び出す
```
use App\Models\Book;
use Illuminate\Http\Request;
```
### 【ルーティングとviewの準備】
#### 1. /routes/web.phpに以下の記述を追加
```
// 本のダッシュボード表示(books.blade.php)
Route::get('/', function () {
return view('welcome');
});
// 新「本」を追加
Route::post('/books', function (Request $request) {
//
});
// 本を削除
Route::delete('/book/{book}', function (Book $book) {
//
});
```
#### 2. resources/views/の直下にbooks.blade.php を作成して以下を追記
```
<!-- resources/views/books.blade.php -->
@extends('layouts.app')
@section('content')
<!-- Bootstrapの定形コード… -->
<div class="card-body">
<div class="card-title">
本のタイトル
</div>
<!-- バリデーションエラーの表示に使用-->
@include('common.errors')
<!-- バリデーションエラーの表示に使用-->
<!-- 本登録フォーム -->
<form action="{{ url('books') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- 本のタイトル -->
<div class="form-group">
<div class="col-sm-6">
<input type="text" name="item_name" class="form-control">
</div>
</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
```
#### 3. /resources/views/common/errors.blade.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
```
### 【登録&表示処理の実装】
#### 1. web.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);
}
//以下に登録処理を記述(Eloquentモデル)
// Eloquent モデル
$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. web.php の本のダッシュボード表示を以下にアップデート
```
Route::get('/', function () {
$books = Book::orderBy('created_at', 'asc')->get();
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
});
```
#### 3. /resources/views/books.blade.phpの</form>タグの下行に追記
```
<!-- 現在の本 -->
@if (count($books) > 0)
<div class="card-body">
<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>
</div>
@endif
```
### 【削除処理の実装】
#### 1. /resources/views/books.blade.phpの<!-- 本: 削除ボタン -->下の<td></td>要素内に追加
```
<form action="{{ url('book/'.$book->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
削除
</button>
</form>
```
#### 2. web.phpにて本を削除』のルート定義を追加編集
```
Route::delete('/book/{book}', function (Book $book) {
$book->delete(); //追加
return redirect('/'); //追加
});
```
### 【更新画面表示の処理を作成】
#### 1. web.phpに更新画面表示と更新処理を追記
```
//「本」を更新画面表示
Route::get('/booksedit/{book}',function(Book $book){
return view('booksedit', ['book' => $book]);
});
//「本」を更新処理
Route::post('books/update',function(Request $request){
});
```
#### 2. books.blade.phpに更新ボタンを追記
```
<td>
<form action="{{ url('booksedit/'.$book->id) }}" method="GET"> {{ csrf_field() }}
<button type="submit" class="btn btn-primary">更新 </button>
</form>
</td>
```
#### 3. booksedit.blade.phpをviewの配下に新規作成し以下追記
```
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-md-12">
@include('common.errors')
<form action="{{ url('books/update') }}" method="POST">
<!-- item_name -->
<div class="form-group">
<label for="item_name">Title</label>
<input type="text" name="item_name" class="form-control" 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_field() }}
<!--/ CSRF -->
</form>
</div>
</div>
@endsection
```
### 【更新処理の実装】
#### 1. web.phpの更新処理を以下に上書き
```
Route::post('books/update',function(Request $request){
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
// 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('/');
});
```
### 【処理をコントローラーにまとめる】
#### 1. artisanコマンドでコントローラー作成
`php artisan make:controller BooksController --resource`
#### 2. BooksController内の6行目から以下2行を追加
```
use App\Models\Book;
use Validator;
```
#### 3. web.phpの上部に以下の1行を追加
```
use Illuminate\Support\Facades\Route;
use App\Models\Book;
use Illuminate\Http\Request;
use App\Http\Controllers\BooksController;//追記
```
#### 4. 処理を移行する
web.phpの本のダッシュボード表示処理の中身をコピー
```
Route::get('/', function () {
↓↓↓↓↓↓↓↓ここから↓↓↓↓↓↓↓↓
$books = Book::orderBy('created_at', 'asc')->get();
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
↑↑↑↑↑↑↑↑ここまで↑↑↑↑↑↑↑↑
});
```
#### 5. BooksController内のindexメソッドにコピーした処理を貼り付け
```
public function index()
{
↓↓↓↓↓↓↓↓ここから貼り付け↓↓↓↓↓↓↓↓
$books = Book::orderBy('created_at', 'asc')->paginate(3);
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
↑↑↑↑↑↑↑↑ここまで貼り付け↑↑↑↑↑↑↑↑
}
```
#### 6. web.phpのさっき切り取ったルーティングを以下に変更
`Route::get('/', [BooksController::class, 'index']);`
#### 7. その他も同様に処理を移行してweb.phpの最終完成形
```
//本 ダッシュボード表示
Route::get('/', [BooksController::class, 'index']);
//登録処理
Route::post('/books',[BooksController::class, 'store']);
//更新画面
Route::get('/booksedit/{books}',[BooksController::class, 'edit']);
//更新処理
Route::post('/books/update',[BooksController::class, 'update']);
//本を削除
Route::delete('/book/{book}',[BooksController::class, 'destroy']);
```
### 【ページネーション実装】
#### 1. BooksControllerのindexの処理を以下に変更
```
public function index() {
$books = Book::orderBy('created_at', 'asc')->paginate(3);
}
```
#### 2. books.blade.phpの@endsectionの上に以下をコピペ
```
<div class="row">
<div class="col-md-4 offset-md-4">
{{ $books->links()}}
</div>
</div>
```
#### 3. App\Http\Middleware\TrustProxiesの以下の部分を変更
```
protected $proxies;//変更前
↓
protected $proxies = '*';//変更後
```
#### 4.App\Providers\AppServiceProviderでBootstrap5対応コードに変更
```
use Illuminate\Pagination\Paginator;//ここ追記
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Paginator::useBootstrapFive();//ここ追記
}
```