Laravel 簡単なアプリケーション作成(1)
Laravelを利用して簡単なアプリケーションを作成する手順
環境
前回作成したsampleappを流用する。
作成する画面、機能の概要
ID | URL | 機能 |
---|---|---|
1 | /home | トップ画面表示 |
2 | /auth/register | ユーザ登録およびメール送信 |
3 | /auth/login | Login |
4 | /auth/logout | Logout |
トップ画面の作成
http://homestead.test/home にアクセスしたらTop画面が表示されるようにする。
ディレクトリ構成
(base) mbp:sampleapp username$ tree -d -L 1
.
├── app
├── bootstrap
├── config
├── database
├── public
├── resources
├── routes
├── storage
├── tests
└── vendor
ルーティング定義追加
// add
Route::get('/home', function(){
return view('home');
});
TOP画面のHTML作成(新規作成)
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
Hello! World!
</body>
</html>
http://homestead.test/home にアクセスしたらTop画面が表示される.
テストフレームワーク PHPUnit を試してみる
Laravelには、PHPを代表するテストフレームワークである「PHPUnit」が同梱される。
以下の2つのテストを行う。
- トップ画面のHTTPステータスコードが200
- トップ画面のレスポンスに"Hell! World!"の文字列が含まれていること
テストコードファイルの作成
(base) mbp:sampleapp username$ pwd
/Users/username/code/sampleapp
(base) mbp:sampleapp username$ php artisan make:test HomeTest
Test created successfully.
(base) mbp:sampleapp username$
生成されたテストファイル
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HomeTest extends TestCase
{
/**
* A basic feature test example.
*
* @return void
*/
public function testExample()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
以下に変更、追加
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HomeTest extends TestCase
{
/**
* A basic feature test example.
*
* @return void
*/
public function testExample()
{
$response = $this->get('/home');
$response->assertStatus(200);
}
public function testBody(){
$response = $this->get('/home');
$response-> assertSeeText("Hell! World!");
}
}
トップ画面のテストを実行
(base) mbp:sampleapp username$ pwd
/Users/username/code/sampleapp
(base) mbp:sampleapp username$ vendor/bin/phpunit tests/Feature/HomeTest.php
PHPUnit 7.5.9 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 100 ms, Memory: 14.00 MB
OK (2 tests, 2 assertions)
(base) mbp:sampleapp username$
ユーザ登録の実装
ユーザ登録機能の実装を通じてリクエストの受信とバリデーション機能(検証、認可)に関して学ぶ。
手順概要
- データベース準備
- 認証/登録機能のコードを確認、ルーティングに追加
- 登録画面を作成
データベース準備
ユーザ情報を登録するテーブルを作成する。テーブル作成にはマイグレーション機能を利用する。
マイグレーション機能とはデータベースのスキーマ作成やデータ投入などをプログラムコードを使って処理する機能。
マイグレーションを行うためのファイルはdatabase/migrationsにある。
databaseディレクトリの内容
(base) mbp:sampleapp username$ tree database/
database/
├── factories
│ └── UserFactory.php
├── migrations
│ ├── 2014_10_12_000000_create_users_table.php
│ └── 2014_10_12_100000_create_password_resets_table.php
└── seeds
└── DatabaseSeeder.php
3 directories, 4 files
マイグレーションファイル
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
マイグレーション実行
vagrantで仮想環境にログイン
# cd ~/Homestead
# vagrant ssh
# cd ~/code/sampleapp/
vagrant@homestead:~/code/sampleapp$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
vagrant@homestead:~/code/sampleapp$
MySQLに接続して作成したテーブルを確認する
vagrant@homestead:~/code/sampleapp$ mysql --host=localhost --user=homestead --password=secret homestead
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.25-0ubuntu0.18.04.2 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show tables from homestead ;
+---------------------+
| Tables_in_homestead |
+---------------------+
| migrations |
| password_resets |
| users |
+---------------------+
3 rows in set (0.00 sec)
mysql>
認証/登録機能をルーティングに追加
登録処理はコントローラーで処理する。コントローラーはMVCアーキテクチャを構成する要素の1つ。
サービス利用者からの入力、受信結果を返却するためのビューの選択、生成などを担う。
登録処理はRegisterControllerクラスの showRegistorationForm メソッドと registor メソッドで行う。
ルーティング定義の追加
Route::get('auth/register', 'Auth\RegisterController@showRegistrationForm');
Route::post('auth/register', 'Auth\RegisterController@register');
登録画面の作成
resources/views/auth にregister.blade.php として保存
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<h1>ユーザ登録フォーム</h1>
<form name="registform" action="/auth/register" method="post">
{{csrf_field()}}
名前:<input type="text" name="name" size="30"><span>{{ $errors->first('name') }} </span><br />
メールアドレス:<input type="text" name="email" size="30"><span>{{ $errors->first('email') }} </span><br />
パスワード:<input type="password" name="password" size="30"><span>{{ $errors->first('password') }} </span><br />
パスワード(確認):<input type="password" name="password_confirmation" size="30"><span>{{ $errors->first('password_confirmation') }} </span><br />
<button type='submit' name='action' value='send'>送信</button>
</form>
</body>
</html>
TOP画面を変更する
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
Hello!
@if (Auth::check())
{{\Auth::user()->name}}さん
@else
ゲストさん<br />
<a href="/auth/register">会員登録</a>
@endif
</body>
</html>
TOP画面にアクセスし、ユーザ登録フォームが表示されることを確認する。
試しに適当な値を入力し、送信ボタンを押し、 /home のページにリダイレクトされ、ログイン後の画面が表示される事を確認する。
最後に、DBに登録されたデータを確認してみる。
vagrant@homestead:~$ mysql --host=localhost --user=homestead --password=secret homestead
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 5.7.25-0ubuntu0.18.04.2 (Ubuntu)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select * from users;
+----+-----------------+----------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name | email | email_verified_at | password | remember_token | created_at | updated_at |
+----+-----------------+----------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| 1 | xxx | xxxx.com | NULL | xxxxx| NULL | 2019-05-01 08:44:24 | 2019-05-01 08:44:24 |
+----+-----------------+----------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
1 row in set (0.00 sec)
mysql>
ユーザ認証
ログイン機能とログアウト機能を実装する
ルーティング追加
// Login Form
Route::get('/auth/login', 'Auth\LoginController@showLoginForm');
Route::post('/auth/login', 'Auth\LoginController@login');
// Logout
Route::get('/auth/login', 'Auth\LoginController@logout');
ログインフォーム実装
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<h1>ログインフォーム</h1>
@isset($mesage)
<p style="color:red">{{$message}}</p>
@endisset
<form name="loginform" action="/auth/login" method="post">
{{csrf_field()}}
mailaddress: <input type="text" name="email" size="30" value="{{old('email')}}"><br />
password: <input type="password" name="password" size="30"><br />
<button type='submit' name='action' value='send'>Login</button>
</form>
</body>
</html>
TOP画面にログアウト機能を追加
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
Hello!
@if (Auth::check())
{{\Auth::user()->name}}さん<br />
<a href="/auth/logout">Logout</a>
@else
ゲストさん<br />
<a href="/auth/login">Login</a><br />
<a href="/auth/register">会員登録</a>
@endif
</body>
</html>
ログアウト後の遷移先を変更する
/app/Http/Controllers/Auth/LoginController.php に以下のメソッドをオーバライドする
// Override
public function logout(\Illuminate\Http\Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
// return $this->loggedOut($request) ?: redirect('/');
return $this->loggedOut($request) ?: redirect('/home');
}
元は sampleapp/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
に定義されるメソッドだが、vendor/ 以下に直接変更を加えず、オーバライドしておこう