# 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>&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> </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();//ここ追記 } ```