作成日:2021/04/12 更新日:2023/03/03
#8 Laravelアプリでデータを新規登録する方法
①以前のデータの確認
続いて新規登録処理の実装に移りましょう。以前作成した「index.php」の、下記の部分です。
<div id="input_form">
  <form action="index.php" method="POST">
    <input type="text" name="inputName">
    <input type="submit" value="登録">
  </form>
</div>
/* 新規氏名をデータベースへ登録 */
if(!empty($_POST['inputName'])){
  try{
    $sql  = 'INSERT INTO sortable(name) VALUES(:ONAMAE)';
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(':ONAMAE', $_POST['inputName'], PDO::PARAM_STR);
    $stmt->execute();
    header('location: http://localhost:8001/');
    exit();
  } catch (PDOException $e) {
      echo 'データベースにアクセスできません!'.$e->getMessage();
  }
}
②登録ロジックを作成 bladeテンプレート(view)
今回もまずはview層から着手しましょう。drag-areaの時と同じ様に、layoutsフォルダに「registrations.blade.php」というファイルを作成します。
<form action="{{ url( 'register' )}}" method="POST">
  {{ csrf_field() }}
  <input type="text" name="inputName" placeholder="新メンバー名を入力">
  <input type="submit" value="登録">
</form>
「csrf_field()」という記述は、後ほど説明いたします。
このファイルを「sortable.blade.php」でincludeさせます。
{{ csrf_field() }}
↓
<input type="hidden" name="_token" value="***********************************">
③画面表示ロジックを作成 bladeテンプレート(view)
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>8001-cri-sortable</title>
  <link href="{{ asset('css/style.css')}}" rel="stylesheet">
</head>
<body>
<div id="wrapper">
<div id="input_form">
  @include('layouts.registrations')  /* registrations.blade.phpを読み込む */
</div>
<div id="drag-area">
  @include('layouts.drags')
</div>
</div>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
  <script src="{{ asset('js/main.js')}}"></script>
</body>
</html>
ファイル:resources/views/sortable.blade.php
④新規登録用のコントローラーを作成(controller)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sortable;
class SortableController extends Controller
{
    public function index(){
      $sortable = Sortable::orderBy('id', 'asc')->get();
      return view('sortable', [
        'sortables' => $sortable
      ]);
    }
    public function register(Request $request){
      $sortable = new Sortable;
      $sortable->name = $request->inputName;
      $sortable->save();
      return redirect('/');
    }
}
namespaceがApp\Http\Controllersなので App/Http/Controllers/ 内にSortableController.phpという名前で保存します。
引数で渡している$requestには、ブラウザの画面で「登録」ボタンを押下した際に送信されるHTTPrequestの中身が入ります。
クラスをnewすることで、sortablesテーブルまでの接続指示を、および登録するnameカラムの値を格納したら save()メソッドで登録処理INSERTを実行させる処理、を$sortableの中にいれます。
全ての処理が完了したらredirect()メソッドでリダイレクト処理を実行します。 リダイレクト先は元々いた画面に戻りたいので「/」とします。
⑤ルーティングの設定(web.php)
?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', 'SortableController@index');
Route::post('/register', 'SortableController@register');
/registerがPOSTリクエストされると、コントローラーのregisterメソッドを呼び出します。
ここまで記述を終えたら、早速画面から登録処理を試してみましょう。

名前を入れて、登録をクリックすると...

新規に登録されます。

もちろんデータベースにも登録されています。
#9 LaravelでAjaxのデータを登録する方法
①以前のデータの確認
続いて新規登録処理の実装に移りましょう。以前作成した「index.php」の下記の部分です。
/* 移動したようその座標をデータベースへ登録 */
if(!empty($_POST['left'])){
  try{
    $sql  = 'UPDATE `sortable` SET `left_x` = :LEFT, `top_y` = :TOP WHERE `id` = :NUMBER';
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(':LEFT'  , $_POST['left'], PDO::PARAM_INT);
    $stmt->bindValue(':TOP'   , $_POST['top'],  PDO::PARAM_INT);
    $stmt->bindValue(':NUMBER', $_POST['id'],   PDO::PARAM_INT);
    $stmt->execute();
  } catch (PDOException $e) {
    echo $e->getMessage();
  }
}
<script>
$(function(){
  $('.drag').draggable({
    containment:'#drag-area',
    cursor:'move',
    opacity:0.6,
    scroll:true,
    zIndex:10,
    /* ==========STOP処理====================================== */
    stop:function(event, ui){
      var myNum  = $(this).data('num');
      var myLeft = (ui.offset.left - $('#drag-area').offset().left);
      var myTop  = (ui.offset.top  - $('#drag-area').offset().top);
      /* ==========AJAX通信================= */
      $.ajax({
        type:'POST',
        url :'http://localhost:8001/',
        data: {
          id  :myNum,
          left:myLeft,
          top :myTop
        }
      }).done(function(){
         console.log('成功');
      }).fail(function(XMLHttpRequest, textStatus, errorThrown){
         console.log(XMLHttpRequest.status);
         console.log(textStatus);
         console.log(errorThrown);
      });
      /* ==========/AJAX通信================= */
        console.log("左: " + myLeft);
        console.log("上: " + myTop);
    }
    /* ==========/STOP処理====================================== */
  });
});
</script>
②Ajaxの修正とCSRF対策について。main.jsの修正
Ajaxの通信先をLaravelのアプリケーションに変更する必要があります。
$.ajaxSetup({  /* ①-追加 */
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
});
$.ajax({
  type:'POST',
  url: '/update',  /* ②-変更 */
  data: {
    id  :myNum,
    left:myLeft,
    top :myTop
  }
}).done(function(){
①.ajaxのリクエスト通信にheadersを追加し、CSRFに関する記述をする
CSRFとは悪意のある攻撃(エクスプロイト)のことです。LaravelではPOSTされたデータやHTMLフォームから来たデータがCSRF攻撃だった場合に、それを防ぐ仕組みが用意されています。
TOKENとは暗号鍵やワンタイムパスワードなどを生成する仕組みのことです。
POSTやHTMLフォームからデータを受ける場合は、隠しCSRFトークンフィールドをmetaタグやフォームに埋め込み、データの有効性をチェックするようにしましょう。
②urlの値を「/update」へ変更する
以前は「localhost:8001」を指定していた部分です。あとでルーティングファイル「web.php」を修正し、「/update」が呼ばれたらControllerの更新処理を呼び出すように設定します。Ajaxのheadersに渡すためのCSRFトークンをHTMLに記述する
<meta name="csrf-token" content="{{ csrf_token() }}">
③Controllerに更新処理を追記する。
コントローラーのSortableController.phpに記述してあるregister()メソッドの下に、新たに update()メソッド を追記します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Sortable;
class SortableController extends Controller
{
    public function index(){
      $sortable = Sortable::orderBy('id', 'asc')->get();
      return view('sortable', [
        'sortables' => $sortable
      ]);
    }
    public function register(Request $request){
      $sortable = new Sortable;
      $sortable->name = $request->inputName;
      $sortable->save();
      return redirect('/');
    }
    /* ↓↓↓ここに追記↓↓↓ */
    public function update(Request $request){
      $inputs   = $request->all();
      $s        = new Sortable;
      $sortable = $s->find($inputs['id']);
      $sortable->left_x = $inputs['left'];
      $sortable->top_y  = $inputs['top'];
      $sortable->save();
      return redirect('/');
    }
}
・Ajax通信で仮想サーバへ飛んできたHTTPRequestの内容を取得
・requestの中からidを取り出し、テーブルから該当するレコードを探しに行く
・該当するレコードのleft_xとtop_yカラムの値を更新し、更新登録を完了する。
・初期画面へリダイレクトする。
▼解説
$inputs = $request->all();
Ajaxで送信した内容はHTTPRequestという形でwebサーバ(MAMPの仮想サーバ)に入ってきます。
そのrequestの中に、Ajaxで格納したdata(idやleft_x、top_yの座標)が入っているので、その値を取得するために上記の様な処理を行います。
$sortable = $s->find($inputs['id']);
find()メソッドで$sortableの中から該当するidを持っているレコードを探します。
※「$sortable」はModelの「Sortable.php」の内容を持っています。
$sortable->left_x = $inputs['left'];
$sortable->left_y = $inputs['top'];
$sortable->save();
$sortable = $s->find($inputs['id']);
④ルーティングファイルweb.phpを修正
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', 'SortableController@index');
Route::post('/register', 'SortableController@register');
Route::post('/update', 'SortableController@update');
 
完成したLarabelアプリの図解
【前提】MAMP、Homebrew、Composer、VS Code、ブラウザ をインストールしておく
【初期設定】
・開発環境フォルダを作成
・フォルダに対しMAMPのhttpd-vhosts.confでバーチャルホストを設定
・ターミナルでComposerを使ってLaravel本体をインストールする
・Laravelの.envファイルをMAMP環境に編集
・Laravelの/config/database.phpを.envの内容に編集
・phpMyAdminでデータベースを作成
・ターミナルを使ってartisanコマンドでLaravelのマイグレーションファイルを作成
・Laravelの/database/migration/にあるマイグレーションファイルを編集
・ターミナルを使ってartisanコマンドでマイグレーションを実行(DBにテーブルができる)
 
#10 Laravelでアプリを作ってみよう
応用課題として自分用の「タスク管理ツール」を作成してみましょう。

HTML&CSSデータ ダウンロード
まずは学習してきた流れ通り、Laravelプロジェクトを作成するところから始めましょう。
ここでのLaravelのバージョンは8.75.0、PHPは7.4.1とします。
前準備
開発ディレクトリを作成

「8027-MyTASK」という名称にしました
開発ディレクトリにLaravelプロジェクト「MyTASK」を作成
ComposerでLalavelをインストールしましょう。ここではプロジェクト名を「MyTASK」にしました。
cd 8027-MyTASK [enterkey]
composer create-project laravel/laravel MyTASK --prefer-dist
開発ディレクトリをMAMPでバーチャルホストを設定
MAMPでポート番号のバーチャルホストを設定します。#5 Laravelの環境構築を参考にしましょう。設定後にMAMPを再起動はお忘れなく。
Listen 8027
<virtualhost *:8027>
  DocumentRoot "/Users/ユーザ名/job/stg/8027-MyTASK/MyTASK/public"
</virtualhost>
Laravel環境設定
①.envファイルのデータベース情報の設定②/config/database.phpで.env情報を設定
Laravelの環境設定を変更する .env ファイルを参考にしましょう。
DB_HOST=localhost
DB_PORT=8889
DB_DATABASE=cbc_mytask
DB_USERNAME=root
DB_PASSWORD=root
$ php artisan config:cache
データベースを作成し、マイグレーションを使ってテーブル、カラムを作成
ここではデータベースcbc_mytaskを作成し、テーブル名をtasks、カラムにidとタスクを入れるtaskというカラムを作りました。

データベース名を「cbc_mytask」とします。
$ php artisan make:migration create_tasks_table --create=tasks
public function up()
{
  Schema::create('tasks', function (Blueprint $table) {
      $table->integer('id')->autoIncrement();
      $table->text('task')->nullable(false);
  });
}

$ php artisan migrate
 
データベースが作成できました
Modelを作る
#7 ③データを取得するモデルSortable.phpを作るを参照してみてください。ここではモデル名をTaskとしました。
$ php artisan make:model Task
ファイルの編集ですが今回も日付記録のカラムがないので、Task.php内のTaskクラスに、タイムスタンプfalseの設定を追記しておきましょう。
public $timestamps = false;  /* 追加 */
Controllerを作る
コントローラーの理解
今回のアプリで行う処理は主に3つです。
1.初期表示(SELECT)・・・テーブルから全てのデータを取得し、タスク表示箇所へ反映する。
2.登録(INSERT)・・・入力されたタスク名をテーブルに登録する。
3.完了(DELETE)・・・完了ボタンが押されたら、そのタスクに該当するレコードをテーブルから削除する。(物理削除する)
2.登録(INSERT)・・・入力されたタスク名をテーブルに登録する。
3.完了(DELETE)・・・完了ボタンが押されたら、そのタスクに該当するレコードをテーブルから削除する。(物理削除する)
(DELETEという通信方法もありますが、今回はPOSTで作りましょう)
また、完了ボタンを押下した際に、本当にそのタスクを完了してよいかの確認ができる様に、アラート機能をjsで実装をしてください。 ajaxの通信が始まる前に記述しましょう。googleでjs 確認ダイアログ コンファームなどのキーワードで検索してみましょう。

いいえが押された場合は、削除処理が進まないようにします。
コントローラーを作る
TaskController.phpファイルを作ります。
$ php artisan make:controller TaskController
コントローラーに表示、登録、削除のメソッドを作成する
TaskControllerクラス内で、テーブル全件取得と、登録、削除のメソッドを作成します。
class TaskController extends Controller
{
  public function テーブル全件取得メソッド(){
    処理
  }
  public function 登録メソッド(){
    処理
  }
  public function 削除メソッド(){
    処理
  }
}
削除のメソッドはLaravelマニュアル モデル削除 を見ながら作りましょう。
またgoogleなどの検索エンジンで「Laravel 削除メソッド」で探してみましょう。
削除するときは、データベースを取得しているクラス「Task」にアクセスし、特定のidを特定して、削除するメソッドを実行します。 クラスにはスコープ演算子を使ってアクセスしてみましょう。
Class::静的プロパティ(変数)、Class::静的メソッド(関数)
「::(ダブルコロン)」はスコープ演算子
Class外部からClassをスコープ(範囲指定)して静的なプロパティ、メソッドにアクセスする。
(例)
class Aisatsu
{
  public static $hello = 'おはよう';
  public static function bye(){
    return 'ばいばい';
  }
}
echo Aisatsu::$hello;
echo Aisatsu::bye();
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task; /* 名前空間を設定します */
class TaskController extends Controller
{
  public function index(){                      /* indexメソッドを追加します */
    $task = Task::orderBy('id', 'asc')->get();  /* Taskクラスを使ってtasksテーブル全件取得を指示 */
    /* task.blade.phpに対し(第1引数)、taskカラムのデータをtasksに渡す(第2引数) */
    return view('task', [
      'tasks' => $task
    ]);
  }
  public function register(Request $request){
    $task = new Task;
    $task->task = $request->task;
    $task->save();
    return redirect('/');
  }
  public function delete(Request $request){
    $task = Task::find($request->id);  /*Taskクラスを使って、ajaxで渡ってきたidをセットする*/
    $task->delete();                   /*指定されたidを削除する*/
    /* $task = Task::find($request->id)->delete(); //これでも可 */
    return redirect('/');
  }
}
web.phpでルーティングを設定する
/routes/web.phpでルートURLが呼ばれたら、Controllerのindex()メソッドの処理を実行させます。#7 ⑤ルーティングのweb.phpを修正するを参考にしましょう。
/* Route::get('/', function () {
     return view('welcome');
}); */
Route::get('/',          'App\Http\Controllers\TaskController@index');
Route::post('/register', 'App\Http\Controllers\TaskController@register');
Route::post('/delete',   'App\Http\Controllers\TaskController@delete');
bladeテンプレートでViewを作る
ダウンロードした過去制作のindex.phpを編集しながら、3つの機能ごとにファイルを分割しよう
機能の部品であるregists.blade.phpとmyTasks.blade.phpはlayoutsディレクトリに入れましょう。
CSSやJSファイルは公開フォルダの/public/ディレクトリ内に入れます。
tasks.blade.phpに2つの機能ファイルを@includeさせましょう。
登録する部分は、index.htmlの「formタグ」部分をコピーして、#8 ②作ったregistrations.blade.phpを参考に、 作ってみましょう。
表示する部分は、index.htmlの「ループさせて表示させる」部分を探し出して、 #7 ②作ったdrags.blade.phpを参考に、作ってみましょう。
cssやjsを読み込ませる際にも{{ asset(***/***.***) }}で読み込ませましょう。
答え
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="csrf-token" content="{{ csrf_token() }}">
  <title>MyTasks</title>
  <link href="{{ asset('css/reset.css')}}" rel="stylesheet">
  <link href="{{ asset('css/style.css')}}" rel="stylesheet">
</head>
<body>
  <div id="wrap" class="wrap">
    <div class="task">
      <!-- タスク作成エリア -->
      <div class="task__new">
        <h2>新しいタスクを作成</h2>
        @include('layout.regists')
      </div>
      <!-- タスク一覧表示エリア -->
      <div class="task__area">
        <h2>わたしのタスク一覧</h2>
        <ul class="task__area-list">
          @include('layout.myTasks')
        </ul>
      </div>
    </div>
  </div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script src="{{ asset('js/main.js')}}"></script>
</body>
</html>
<form action="{{ url( 'register' )}}" method="POST">
  {{ csrf_field() }}
  <input type="text" name="task" maxlength="30" placeholder="タスクを入力してください">
  <input type="submit" value="追加">
</form>
@foreach($tasks as $task)
  <li>
    <p>{{ $task->task }}</p>
    <button class="delete_btn" data-id="{{ $task->id }}">完了</button>
  </li>
@endforeach
ajaxの通信ロジックを作る
$(function(){
  $('.delete_btn').on('click', function(){
    var Id = $(this).data('id');
    /*console.log(Id);*/
    if(confirm("タスクを完了してよいでしょうか?")){
      /* ==========AJAX通信================= */
      $.ajaxSetup({
        headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
      });
      $.ajax({
        type:'POST',
        url: '/delete',
        data: {
          id: Id
        }
      }).done(function(){
         /*console.log('成功');*/
         location.reload();
      }).fail(function(XMLHttpRequest, textStatus, errorThrown){
         console.log(XMLHttpRequest.status);
         console.log(textStatus);
         console.log(errorThrown);
      });
      /* ==========/AJAX通信================= */
    }
  });
});
実際に動かしてみよう!
Laravelのデバッグバーをインストールする
Controllerの設定あたりでエラーが出ることが増えると思います。 そんなときはLaravelのデバッグツールを使ってエラーの原因を探ることができます。
$ composer require barryvdh/laravel-debugbar
APP_DEBUG=true
$ php artisan config:cache
また、Laravel8のマニュアル を見て基本的な動作を習得しましょう。
 入門
入門 基礎
基礎 応用
応用 実践フロントエンド
実践フロントエンド 実践バックエンド
実践バックエンド デザイン
デザイン キッズ
キッズ