Laravel5で変更に強いアプリケーションを作成する。
サンプルとして経費(本)を記録するだけのWebアプリケーションを作成。
日付、タイトル、価格、URLを1テーブルにしてMySQLへ格納。
Laravelインストール
% composer create-project laravel/laravel keihi
% cd keihi
% php artisan -V
Laravel Framework version 5.1.20 (LTS)
名前空間を更新
Keihiという名前空間にします。
// namespaceを「App」から「Keihi」へ変更
% php artisan app:name Keihi
namespace指定してある箇所が全部以下のように変更されます。
composer.json
"psr-4": {
- "App\\": "app/"
+ "Keihi\\": "app/"
}
app/Console/Kernel.php
<?php
-namespace App\Console;
+namespace Keihi\Console;
Databaseを用意
MAMPでMYSQLサーバー起動、UTF8でDB作成。
以下、MAMPのソケットで繋ぐときに必要な処理。
UNIX_SOCKET追記
/config/database.php
'mysql' => [
'driver' => 'mysql',
'unix_socket' => env('DB_UNIX_SOCKET'),// 1行追記
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
.envのDB設定を編集してDB_UNIX_SOCKETは追記。
.env
DB_UNIX_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
DB_HOST=localhost
DB_DATABASE=keihi_db
DB_USERNAME=test
DB_PASSWORD=test
マイグレーション作成
作成コマンド
% php artisan make:migration create_keihi_table --create=keihi
Created Migration: 2015_10_23_235515_create_keihi_table
ファイル編集
/database/migrations/2015_10_23_235515_create_keihi_table.php
public function up()
{
Schema::create('keihi', function (Blueprint $table) {
$table->increments('id'); // ID
$table->char('title', 100); // タイトル
$table->integer('price'); // 価格
$table->text('url'); // URL
$table->timestamps(); // 作成時刻
});
}
マイグレーション実行
MySQLにテーブルが作成。(keihi以外はデフォルトで存在するもの)
% php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2015_10_23_235515_create_keihi_table
エレクエント作成
Keihiモデル(/app/Keihi.php)を作成。
% php artisan make:model Keihi
エレクエント編集
Keihiモデルに紐づくテーブルを「keihi」に設定。
/app/Keihi.php
<?php
namespace Keihi;
use Illuminate\Database\Eloquent\Model;
class Keihi extends Model
{
protected $table = 'keihi';
}
リポジトリ作成
インターフェース作成
/app/Repositories/KeihiInterface.php
<?php
/**
* Interface KeihiInterface
*/
interface KeihiInterface
{
/**
* 取得
* @param $id
* @return mixed
*/
public function get($id);
/**
* 一覧取得
* @return mixed
*/
public function getList();
/**
* 更新
* @param $id
* @param $data
* @return mixed
*/
public function update($id, $data);
/**
* 新規登録
* @param $data
* @return mixed
*/
public function create($data);
/**
* 削除
* @param $id
* @return mixed
*/
public function delete($id);
}
リポジトリ実装
インターフェースを使用して実装します。
コンストラクタでエレクエントモデルを依存注入します。
/app/Repositories/KeihiRepository.php
<?php
namespace Keihi\Repositories;
use Keihi\Repositories\KeihiInterface;
use Keihi\Keihi;
/**
* Class KeihiRepository
* @package Keihi\Repositories
*/
class KeihiRepository implements KeihiInterface
{
/**
* @var Keihi
*/
protected $keihi;
/**
* @param Keihi $keihi
*/
public function __construct(Keihi $keihi)
{
$this->keihi = $keihi;
}
/**
* 取得
* @param $id
* @return mixed
*/
public function get($id)
{
}
サービスプロバイダー作成
リポジトリ用のサービスプロバイダー作成
php artisan make:provider RepositoryProvider
サービスプロバイダー編集
/app/Providers/RepositoryProvider.php
/**
* Register the application services.
*
* @return void
*/
public function register()
{
// 経費インターフェスと経費リポジトリの連結
$this->app->bind(KeihiInterface::class, KeihiRepository::class);
}
リポジトリサービスプロバイダーの読込
/config/app.php
/*
* Application Service Providers...
*/
Keihi\Providers\AppServiceProvider::class,
Keihi\Providers\AuthServiceProvider::class,
Keihi\Providers\EventServiceProvider::class,
Keihi\Providers\RouteServiceProvider::class,
Keihi\Providers\RepositoryProvider::class,// 1行追加
],
テストデータ投入
シーダー作成
% php artisan make:seeder KeihiSeeder
シーダー編集
エレクエントモデルを利用してテスト用データを記述。
/database/seeds/KeihiSeeder.php
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use Keihi\Keihi;
class KeihiSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
Keihi::create([
'id' => 1,
'title' => 'WEB+DB PRESS Vol.89',
'price' => 1598,
'url' => 'http://www.amazon.co.jp/gp/product/4774176389'
]);
Keihi::create([
'id' => 2,
'title' => 'Docker実践入門――Linuxコンテナ技術の基礎から応用まで (Software Design plus)',
'price' => 2894,
'url' => 'http://www.amazon.co.jp/gp/product/4774176540'
]);
Keihi::create([
'id' => 3,
'title' => 'HTML5 Web標準API バイブル',
'price' => 3218,
'url' => 'http://www.amazon.co.jp/gp/product/4774176540'
]);
}
}
データ投入
% php artisan db:seed --class=KeihiSeeder
単体テスト(PHPUnit)
単体テスト作成
/tests/Repositories/KeihiRepositoryTest.php
<?php
use Keihi\Repositories\KeihiInterface;
class KeihiRepositoryTest extends TestCase
{
protected $repo;
public function setUp()
{
parent::setUp();
$this->repo = $this->app->make(KeihiInterface::class);
}
public function testGet()
{
$result = $this->repo->get(1);
$this->assertSame($result->title, 'WEB+DB PRESS Vol.89');
$this->assertSame($result->price, 1598);
$this->assertSame($result->url, 'http://www.amazon.co.jp/gp/product/4774176389');
}
public function testGetList()
{
$result = $this->repo->getList();
$this->assertCount(3, $result);
$this->assertSame($result[2]->title, 'HTML5 Web標準API バイブル');
$this->assertSame($result[2]->price, 3218);
$this->assertSame($result[2]->url, 'http://www.amazon.co.jp/gp/product/4774176540');
}
}
単体テスト実行
% php vendor/bin/phpunit --tap
TAP version 13
ok 1 - ExampleTest::testBasicExample
ok 2 - KeihiRepositoryTest::testGet
ok 3 - KeihiRepositoryTest::testGetList
1..3
サービス作成
コーントローラー内でリポジトリを操作する為のサービスを作成。
インターフェースを作成。
/app/Services/KeihiServiceInterface.php
/**
* Interface KeihiServiceInterface
* @package Keihi\Services
*/
interface KeihiServiceInterface
{
/**
* 単体取得
* @return mixed
*/
public function get($id);
/**
* 一覧取得
* @return mixed
*/
public function getList();
/**
* 保存
* @param $input
* @param $id | null
* @return $id | null
*/
public function save($input, $id=null);
/**
* 削除
* @param $id
* @return $id
*/
public function delete($id);
/**
* エンティティ作成
* @return $entity
*/
public function createEntity();
インターフェースを使用して実装。
データ検証の役割を持たせる。
/app/Services/KeihiService.php
<?php
namespace Keihi\Services;
use Keihi\Services\KeihiServiceInterface;
use Keihi\Repositories\KeihiInterface;
use Illuminate\Validation\Factory as ValidateFactory;
/**
* Class KeihiService
* @package Keihi\Services
*/
class KeihiService implements KeihiServiceInterface
{
/**
* @var KeihiInterface
*/
protected $keihiInterface;
/**
* @var ValidateFactory
*/
protected $validateFactory;
/**
* @var array
*/
protected $rules = ["title" => "required|max: 100", "price" => "required|integer|min:0|max:100000", "url" => "required"];
/**
* @param KeihiInterface $keihiInterface
* @param ValidateFactory $validateFactory
*/
public function __construct(KeihiInterface $keihiInterface, ValidateFactory $validateFactory)
{
$this->keihiInterface = $keihiInterface;
$this->validateFactory = $validateFactory;
}
/**
* @param $id
* @return mixed
*/
public function get($id)
{
return $this->keihiInterface->get($id);
}
/**
* @return mixed
*/
public function getList()
{
return $this->keihiInterface->getList();
}
/**
* @param $request
* @param $id
* @return $id
*/
public function save($request, $id=null)
{
$input = $request->only(['title', 'price', 'url']);
$v = $this->validateFactory->make($input, $this->rules);
if ($v->fails()) {
return null;
}
if (is_null($id)) {
$id = $this->keihiInterface->create($input);
} else {
$id = $this->keihiInterface->update($id, $input);
}
return $id;
}
/**
* @param $id
* @return bool
*/
public function delete($id)
{
$this->keihiInterface->delete($id);
return true;
}
/**
* @return mixed
*/
public function createEntity()
{
return $this->keihiInterface->createEntity();
}
}
Appサービスプロバイダーに登録。
/app/Providers/AppServiceProvider.php
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// 経費サービス
$this->app->singleton(KeihiServiceInterface::class, KeihiService::class);
}
コントローラー作成。
経費サービスインターフェースを依存注入して使用します。
% php artisan make:controller KeihiController
/app/Http/Controllers/KeihiController.php
<?php
namespace Keihi\Http\Controllers;
use Illuminate\Http\Request;
use Keihi\Http\Requests;
use Keihi\Http\Controllers\Controller;
use Keihi\Services\KeihiServiceInterface;
/**
* Class KeihiController
* @package Keihi\Http\Controllers
*/
class KeihiController extends Controller
{
/**
* @var KeihiServiceInterface
*/
private $keihiService;
/**
* @param KeihiServiceInterface $keihiServiceInterface
*/
public function __construct(KeihiServiceInterface $keihiServiceInterface)
{
$this->keihiService = $keihiServiceInterface;
}
/**
* 一覧
* @return \Illuminate\Http\Response
*/
public function index()
{
$list = $this->keihiService->getList();
return view('keihi.list', compact('list'));
}
/**
* 新規入力画面
* @return \Illuminate\Http\Response
*/
public function create()
{
$keihi = $this->keihiService->createEntity();
return view('keihi.edit', compact('keihi'));
}
/**
* 新規登録処理
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$id = $this->keihiService->save($request);
return $this->show($id);
}
/**
* 詳細
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$keihi = $this->keihiService->get($id);
return view('keihi.detail', compact('keihi'));
}
/**
* 編集画面
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$keihi = $this->keihiService->get($id);
return view('keihi.edit', compact('keihi'));
}
/**
* 更新処理
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$id = $this->keihiService->save($request, $id);
return $this->show($id);
}
/**
* 削除処理
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->keihiService->delete($id);
return $this->index();
}
}
ルーティング
/app/Http/routes.php
Route::resource('keihi', 'KeihiController');
ルーティングの確認。
% php artisan route:list
+--------+----------+--------------------+---------------+------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+--------------------+---------------+------------------------------------------------+------------+
| | GET|HEAD | / | | Closure | |
| | GET|HEAD | keihi | keihi.index | Keihi\Http\Controllers\KeihiController@index | |
| | POST | keihi | keihi.store | Keihi\Http\Controllers\KeihiController@store | |
| | GET|HEAD | keihi/create | keihi.create | Keihi\Http\Controllers\KeihiController@create | |
| | DELETE | keihi/{keihi} | keihi.destroy | Keihi\Http\Controllers\KeihiController@destroy | |
| | PATCH | keihi/{keihi} | | Keihi\Http\Controllers\KeihiController@update | |
| | GET|HEAD | keihi/{keihi} | keihi.show | Keihi\Http\Controllers\KeihiController@show | |
| | PUT | keihi/{keihi} | keihi.update | Keihi\Http\Controllers\KeihiController@update | |
| | GET|HEAD | keihi/{keihi}/edit | keihi.edit | Keihi\Http\Controllers\KeihiController@edit | |
+--------+----------+--------------------+---------------+------------------------------------------------+------------+