Laravelでユーザー登録のサンプル CRUDをざっくり作成

2018/06/30PHP
Laravelでユーザー登録のサンプル CRUDをざっくり作成

以前プロジェクトまで作ったLaravel5.5。今回はLaravel5.5をチュートリアルを見つつ簡単なユーザー登録機能としてCRUDを一通り作ります。インストールからプロジェクト作成から起動までは「はやりのPHPフレームワークLaravel5.5をMacにインストール」を参考にしてください。
環境については今回は「MAMP」でのローカル開発です。

データベースの作成からマイグレーションの作成

データベースの作成

MAMPのphpMyAdminにアクセスします。今回は「test_project」という名前のデータベースを作成しました。

データベースを作成@complesso.jp

データベースユーザの作成

phpMyAdminのタブメニュー「特権」から「test_admin」ユーザーを作成します。

データベースユーザの作成@complesso.jp

Laravelのデータベース接続設定

Laravelのデータベース接続の設定は「config\database.php」の記述を一部変更します。今回はMySQLなので変更する場所は以下の部分です。

'mysql' => [
      'driver' => 'mysql',
      'host' => env('DB_HOST', '127.0.0.1'),
      'port' => env('DB_PORT', '3306'),
      'database' => env('DB_DATABASE', 'forge'),
      'username' => env('DB_USERNAME', 'forge'),
      'password' => env('DB_PASSWORD', ''),
      'unix_socket' => env('DB_SOCKET', ''),
      'charset' => 'utf8mb4',
      'collation' => 'utf8mb4_unicode_ci',
      'prefix' => '',
      'strict' => true,
      'engine' => null,
    ],

データベースの名前

'database' => env('DB_DATABASE', 'forge'),

データベースのユーザ名

'username' => env('DB_USERNAME', 'forge'),

パスワード

'password' => env('DB_PASSWORD', ''),

変更が必要なのは上記の部分ですなのですが、今回は「.envファイル」の方で設定を変更します。

.envファイルについて

「env(‘DB_DATABASE’, ‘forge’),」の記述を見て「??」と感じた方は多いのではないでしょうか?この「env」というのは「.envファイル」の設定値を読み込むための関数で、第一引数(今回は「DB_DATABASE」とされている)が未設定の場合は第二引数を読みます。ここで「.envファイル」を見てみると、

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

という記述がありますので、このままでは「.envファイル」の定数「DB_DATABASE」の設定値を読んでしまいます。

この場合の対策としては、

「.envファイル」内の定数「DB_DATABASE」の値を「test_project」に変更する。
「config\database.php」内の「’database’ => env(‘DB_DATABASE’, ‘forge’),」を「’database’ => test_project,」にする。

のどちらかの方法があります。

今回は2の方法で進めます。

.envファイルの変更

以下の部分を変更します。

DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

から

DB_DATABASE=test_project
DB_USERNAME=test_admin
DB_PASSWORD=DcVTnfT5s0k2UbKL

に変更します。

(※ローカルのテスト用なのでパスワードは見せていますが、本来は厳重に管理してください。)

テーブルの作成

Laravelの一つの特徴として「マイグレーション」という機能があります。この「マイグレーション」によってデータベースのテーブルの作成や編集などを管理することができます。「マイグレーション」を利用するためには、「マイグレーションファイルの作成」と「マイグレーションの実行」が必要です。

マイグレーションファイルの生成

マイグレーションファイルはArtisanコマンドで生成するので、プロジェクトの直下に移動します。

cd /Applications/MAMP/htdocs/test_project

移動が完了したらマイグレーションファイルの生成です。以下のコマンドを入力してください。今回は「users」というテーブルを作る想定です。

php artisan make:migration create_users_table

マイグレーションファイルの生成に成功すると、

Created Migration: 2018_06_19_025512_create_users_table

となり、「database/migrations」に「yyyy_mm_dd_××××××_create_users_table」という名前のファイルが生成されていると思います。

マイグレーションファイルを編集する

生成されたマイグレーションファイルの中身です。

increments('id');
      $table->timestamps();
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('users');
  }
}

今回は「name」フィールドと「telephone」フィールドを追加します。「$table->string(‘name’);」と「$table->string(‘telephone’);」を追加して以下のように書き換えて下さい。(18,19行目です)文字列型のnameフィールドとtelephoneフィールドを作ってねというところを追加しました。

increments('id');
      $table->string('name');
      $table->string('telephone');
      $table->timestamps();
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('users');
  }
}

型については別途記事作成いたします。

マイグレーションの実行

いよいよマイグレーションを実行します。ディレクトリを移動してしまっている場合は「test_project」直下に移動し、以下のコマンドを入力してください。

php artisan migrate

マイグレーションの実行に成功すれば、

Migration table created successfully.
Migrating: 2018_06_19_025512_create_users_table
Migrated: 2018_06_19_025512_create_users_table

となります。

マイグレーション実行時のエラー

Laravelマイグレーション実行時に以下のようなエラーが出た場合は、

「.envファイル内の10行目「DB_HOST=127.0.0.1」が「DB_HOST=localhost」になってないか?」

「データベースユーザのホストが「127.0.0.1」になっているか?」

を確認してください。

Illuminate\Database\QueryException  : SQLSTATE[HY000] [1045] Access denied for user 'test_admin'@'localhost' (using password: YES) (SQL: select * from information_schema.tables where table_schema = test_project and table_name = migrations)

 at /Applications/MAMP/htdocs/test_project/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
  660|     // If an exception occurs when attempting to run a query, we'll format the error
  661|     // message to include the bindings with SQL, which will make this exception a
  662|     // lot more helpful to the developer instead of just the database's errors.
  663|     catch (Exception $e) {
 > 664|       throw new QueryException(
  665|         $query, $this->prepareBindings($bindings), $e
  666|       );
  667|     }
  668| 

 Exception trace:

 1  PDOException::("SQLSTATE[HY000] [1045] Access denied for user 'test_admin'@'localhost' (using password: YES)")
   /Applications/MAMP/htdocs/test_project/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:68

 2  PDO::__construct("mysql:host=127.0.0.1;port=8889;dbname=test_project", "test_admin", "hvRcVzHo6Vw028AR", [])
   /Applications/MAMP/htdocs/test_project/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:68

 Please use the argument -v to see more details.

モデルの作成

モデルを作る

Laravelのモデル作成にはArtisanコマンドを使用します。今回はusersテーブル用のモデルを作成するので以下コマンドをターミナルに入力してください。

php artisan make:model User
Model already exists!

もともとUserモデルであるUser.phpが存在するのでエラーになりました。一度「app/User.php」を削除してからもう一度実行してみてください。

php artisan make:model User
Model created successfully.

すると無事に成功します。

Seederの実行

LaravelにはSeeding(シーディング)といって初期データを挿入するための「シーダクラス(初期値設定クラス)」が用意されています。初期データ(テストデータ)等を挿入するというめんどくさい作業がこれで割愛されます。

シーダーファイルの生成

シーダーの実行にはまずはシーダーファイルを生成する必要があります。シーダーファイルの生成には以下コマンドです。

php artisan make:seeder UsersTableSeeder
Seeder created successfully.

シーダーファイルの編集

シーダーファイルは「database/seeds/」に生成されます。今回は「/test_project/database/seeds/UsersTableSeeder.php」ですのでエディタで開きます。

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

まずは今回のテーブルを追加します。「use Illuminate\Database\Seeder;」の次の行に「use Illuminate\Database\Eloquent\Model;」と「use App\User;」を追加します。

次に挿入するデータの設定ですが、今回は10人分挿入しますので以下の内容に編集します。

public function run()
    {
        //挿入するデータ
        for($i=0;$i<10;$i++)
        {
          $user = new User;
          $user->name = "テストユーザー" . $i;
          $user->telephone = "0902222000" . $i;
          $user->save();
        }
    }

でき上がったファイルです。

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use App\User;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //挿入するデータ
        for($i=0;$i<10;$i++)
        {
          $user = new User;
          $user->name = "テストユーザー" . $i;
          $user->telephone = "0902222000" . $i;
          $user->save();
        }
    }
}

シーダーの実行

Artisanコマンド「php artisan db:seed」コマンドでシードを実行します。この際に「–class=UsersTableSeeder」をつけてUsersテーブル用のシーダーを実行します。

php artisan db:seed --class=UsersTableSeeder

すると無事にUsersテーブルに10人分のデータが登録されました。

Laravelシーダーの実行@complesso.jp

一覧表示画面の作成

次は登録したデータ表示するための一覧表示画面を作っていきます。「ルート」「コントローラ」「ビュー」あたりをさわっていきます。

ルートの編集

「routes\web.php」を編集します。今回は/users/でユーザーの一覧表示画面にアクセスしたいので以下のように編集します。

/*
|--------------------------------------------------------------------------
| 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('users', 'UsersController@index');

コントローラ

ここでは一覧表示画面用のコントローラの生成から編集までを一通り進めます。

コントローラの生成

ArtisanコマンドでUserのコントローラを生成します。コマンドは以下のとおりです。

php artisan make:controller UsersController
Controller created successfully.

「app\Http\Controllers\UsersController.php」がでているのを確認してください。

コントローラの編集

次は上記で生成した「app\Http\Controllers\UsersController.php」を編集していきます。まずは使いたいモデルを指定します。「use Illuminate\Http\Request;」の次の行に「use App\User;」を追加します。

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UsersController extends Controller
{
    //
}

次は「index」用のアクションを追加します。「public function index()」を追加してデータ取得ようの「$users = User::all();」とビューにデータを渡すための「return view(‘users.index’, [‘users’ => $ausers]);」を追加します。以下の内容を参考にしてください。

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UsersController extends Controller
{
    //一覧表示画面
    public function index()
    {
        $users = User::all();
        return view('users.index', ['users' => $ausers]);
    }
}

ビューの作成

次は一覧表示画面用のビューを生成して編集していきます。

ビューファイルの作成

ビューファイルは「resources\views\◯◯◯◯\×××××.blade.php」として作成します。今回の場合は「resources\views\users\index.blade.php」というディレクトリ名+ファイル名で作成します。まずはテンプレートとなるHTMLですが今回はさくっと「Bootstrap」を使います。

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

    <title>Laravel5.5学習用</title>
  </head>
  <body>
    <table>
      <tr>
        <th>No</th>
        <th>名前</th>
        <th>電話番号</th>
        <th>登録日</th>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </table>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
  </body>
</html>

Laravelのテンプレートエンジンでは「foreach」は「@foreach」とコーディングします。

通常のPHPの場合

foreach($users as $user) {
}

Laravelの場合

@foreach ($users as $user)
@endforeach

Vue.jsがバンドルされているからなのか、「{{ $user->id }}」で各プロパティの値を出力していきます。出力は「{{ }}」と覚えておけば問題なさそうです。改行なども適切に処理されるのでしょうか?このあたりはあとでまた検証が必要です。

早速できたファイルにアクセスしてみます。無事にページが表示されました。

Laravel@complesso.jp

新規登録画面の作成

現在表示されているデータはシーダーで登録した初期データですので、次は新規登録画面を作成します。「名前」と「電話番号」が登録できるようにします。

ビューの編集と作成

先ほど作った一覧表示画面に「新規登録」ボタンを設置し、「新規登録画面」と「登録完了画面」を新たに作ります。

「新規登録」ボタンの設置

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

    <title>Laravel5.5学習用</title>
  </head>
  <body>
    <h1>ユーザー一覧</h1>
    <p><a class="btn btn-default">新規登録</a></p>
    <table>
      <tr>
        <th>No</th>
        <th>名前</th>
        <th>電話番号</th>
        <th>登録日</th>
      </tr>
      @foreach ($users as $user)
      <tr>
        <td>{{ $user->id }}</td>
        <td>{{ $user->name }}</td>
        <td>{{ $user->telephone }}</td>
        <td>{{ $user->created_at }}</td>
      </tr>
      @endforeach
    </table>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
  </body>
</html>

新規登録画面

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

    <title>Laravel5.5学習用</title>
  </head>
  <body>
    <h1>新規登録画面</h1>
    <form method="post" action="/users/add">
      <div class="form-group">
        <label for="titleInput">名前</label>
        <input type="text" class="form-control" id="nameInput" name="name">
      </div>
      <div class="form-group">
        <label for="bodyInput">電話番号</label>
        <input type="text" class="form-control" id="telephoneInput" name="telephone">
      </div>
      <button type="submit" class="btn btn-primary">新規追加</button>
    </form>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
  </body>
</html>

ルートの編集

次はルーティングを編集します。「Route::get(‘users/add’, ‘UsersController@add’);」「Route::get(‘users/store’, ‘UsersController@store’);」を追加します。「store」についてはのちほどコントローラのところで説明します。postの場合とgetの場合でアクションするメソッドをわけています。

/*
|--------------------------------------------------------------------------
| 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('/users', 'UsersController@index');
Route::get('/users/add/', 'UsersController@add');
Route::post('/users/add/', 'UsersController@store');

コントローラの編集

「app\Http\Controllers\UsersController.php」を編集して必要なメソッドを作っていきます。

addメソッドの追加

まずは新規登録画面を表示するためのメソッドを追加します。

public function add() {
  return view('users.add');
}

storeメソッドの追加

次はデータをデータベースに登録するためのstoreメソッドを追加します。データベースのモデルのインスタンスを生成して値をセットする。そして「save()」でデータベースに登録するという流れです。

public function store(Request $request) {
  $user = new User;
  $user->name = $request->name;
  $user->telephone = $request->telephone;
  $user->save();

  return view('users.index');
}

動作確認

「The page has expired due to inactivity. Please refresh and try again.」なんてエラーが表示されましが、こちらは「add.blade.php」のformタグのあとに、「{{ csrf_field() }}」をつけることで解決されます。

ここまでの「add.blade.php」

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

    <title>Laravel5.5学習用</title>
  </head>
  <body>
    <div class="container">
      <h1>新規登録画面</h1>
      <form method="post" action="/users/add">
        {{ csrf_field() }}
        <div class="form-group">
          <label for="titleInput">名前</label>
          <input type="text" class="form-control" id="nameInput" name="name">
        </div>
        <div class="form-group">
          <label for="bodyInput">電話番号</label>
          <input type="text" class="form-control" id="telephoneInput" name="telephone">
        </div>
        <button type="submit" class="btn btn-primary">新規追加</button>
      </form>
    </div>


    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
  </body>
</html>

ここまでの「app\Http\Controllers\UsersController.php」

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UsersController extends Controller {
    //一覧表示画面
    public function index() {
        $users = User::all();
        // return view('users.index', ['users' => $users]);
        return view('users.index', ['users' => $users]);
    }

    public function add() {
      return view('users.add');
    }

    public function store(Request $request) {
        $user = new User;
        $user->name = $request->name;
        $user->telephone = $request->telephone;
        $user->save();

        return view('users.index');
    }
}

編集・更新機能を追加する