#初めに
はじめまして。
今回、Laravelの基礎のアウトプットを兼ねてポートフォリオを作成しましたので、説明します。
#目的
フレームワークLaravelを用いての開発をすることで、下記事項が理解できているかを確認する
・MVCモデル
・Bladeを用いたviewの実装
・フォームリクエストを用いたバリデーションの実装
・Eloquent ORMを用いたCRUDの実装
#スペック
■言語
PHP 7.1.23
JavaScript (jQuery)
HTML
CSS (SASS)
■DBMS
MySQL 5.5.60
■フレームワーク
Laravel Framework 5.8.19
■サーバー
AWS EC2
(DBはRDS、ドメイン、SMTPはXSERVERを使用)
#ポートフォリオの概要
ToDoリスト
PCデザイン(960px以上)
レスポンシブデザイン(500px以下のスマートフォン用)
#ポートフォリオの機能
■ユーザー情報関連
・ユーザー登録
・ログイン・ログアウト
・メールアドレス変更
・パスワード変更
・パスワードリマインダー
・退会
■メイン機能
・タスク一覧表示
・タスク新規作成
・タスク完了処理
・タスク内容編集
・タスク検索
・完了タスクの一覧表示
・完了タスクの検索
・完了タスクの復元処理 (誤って完了させた場合の処置)
・カテゴリー編集
■その他
・お問い合わせ
■タスクの完了・復元処理
(誤って完了した際は復元できるようにしている)
#作製方法
###作製時間
計:105h
1.機能洗い出し :1h
2.画面モック作成 :5h
3.テーブル設計、DB作成 :3h
4.各画面、機能を実装:66h
5.ローカル環境テスト:2h
6.デプロイ:26h
7.本番環境テスト:2h
###作製手順
1.機能の洗い出し:1h
3.テーブル設計、DB作成:3h
マイグレーションにてテーブル作成
4.各画面、機能を実装:66h
①画面モックを元に、html,css,JavaScriptで画面のみ作成 14h
(SASS、FLOCSS設計を使用。)
├──foundation/
| ├──reset.scss
| ├──mixin.scss
| ├──variable.scss
| ├──header.scss
| ├──footer.scss
|
├──layout/
| ├──background.scss
|
└──object/
├──component/
| ├──form.scss
| ├──btn.scss
|
├──project/
| ├──top.scss
| ├──task.scss
| ├──sidebar.scss
| ├──mymenu.scss
|
└──utility/
├──modal.scss
├──err.scss
├──accordion.scss
├──pagination.scss
├──fadein.scss
├──link.scss
②画面をBladeに反映 : 4h
③ログイン、ユーザー登録機能などユーザー情報周りから作成。 : 8h
④CRUDを用いたメイン機能を実装(Eloquentを使用) :12h
タスク一覧表示にはtasksテーブルとcategoriesテーブルをリレーションしてデータを取得している。
(belongsTo結合)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $guarded = array('id');
public function getTaskName()
{
return $this->task_name;
}
public function category()
{
return $this->belongsTo('App\Category','category_id','id');
}
}
⑤例外処理、バリデーションの実装 :16h
⑥メール送信処理、退会処理等の実装 :12h
5.ローカル環境テスト:2h
・各機能の処理が正常終了すること。
・バリデーションの確認
・ログイン情報が保持されていること。(ログアウト後は破棄されていること)
・例外発生時、指定のエラーページに遷移すること。
・スマホサイズ(500px以下)にてレイアウトが崩れないこと。など
6.本番環境へデプロイ:26h
①AWS EC2にてインスタンス作製、セキュリティグループ設定
②EC2インスタンスにLAMP、composer、Laravelをインストール
③configファイルなど設定を変更
④ポートフォリオをアップロード
⑤RDSにDBを構築
⑥MySQLのパーミッション設定
⑦マイグレーションを実行
⑧xserverのSMTPにてメールアカウントを設定
7.本番環境環境テスト:2h
ローカル環境のテストケース + 実機確認(PC:Chrome, スマートフォン:iOS)
#工夫したところ(機能面)
###完了、編集、復元処理後の検索条件の保持
#工夫したところ(実装面)
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SignUpRequest extends FormRequest
{
public function authorize()
{
if($this->path() == 'signup'){
return true;
} else {
return false;
}
}
public function rules()
{
return [
'name' => 'required|between:0,10',
'email' => 'required|email|between:0,255|unique:users',
'password' => 'required|alpha_num_check|size:8|confirmed'
];
}
public function messages()
{
return [
'name.required' => '入力必須です。',
'name.between' => '10文字以内で入力してください。',
'email.required' =>'入力必須です。',
'email.email' =>'メールアドレスの形式で入力してください。',
'email.between' => '255文字以内で入力してください。',
'email.unique' =>'このメールアドレスはすでに使用されています。',
'password.required' =>'入力必須です。',
'password.alpha_num_check' =>'半角英数字にて入力してください。',
'password.size' =>'8桁にて入力してください。',
'password.confirmed' => 'パスワードが確認欄と一致していません。'
];
}
}
###カスタムバリデータを実装
(半角英数字チェックなどLaravel標準にないバリデーションを自作)
<?php
namespace App\Http\Validators;
use Illuminate\Validation\Validator;
use App\User;
use Illuminate\Support\Facades\Auth;
class CustomValidator extends Validator
{
public function validateAlphaNumCheck($attribute, $value, $parameters)
{
return preg_match('/^[A-Za-z\d]+$/', $value);
}
public function validatePassVerifi( $attribute, $value, $parameters){
$id = Auth::id();
$user = User::where('id', $id)->first();
if (Auth::attempt(['email' => $user->email, 'password' => $value])) {
return true;
} else {
return false;
}
}
public function validateSameEmailVerifi($attribute, $value, $parameters){
$user = User::where('email', $value)->where('delete_flg',false)->count();
if($user == 0){
return false;
} else{
return true;
}
}
public function validateSameAuthKeyVerifi($attribute, $value, $parameters){
$auth_key = session()->get( 'auth_key');
if($auth_key !== $value){
return false;
} else{
return true;
}
}
}
※カスタムバリデータはサービスプロバイダに設定
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validators\Validator;
use App\Http\Validators\CustomValidator;
class ValidationServiceProvider extends ServiceProvider
{
public function register(){}
public function boot()
{
$validator = $this->app['validator'];
$validator->resolver(function($translator, $data, $rules, $messages) {
return new CustomValidator( $translator, $data, $rules, $messages);
});
}
}
###例外処理をhandlerクラスのrenderメソッドにまとめて実装
※例外が発生した場合、専用のエラー画面に遷移するようにしている
(テストのため、メール送信機能にてエラーが発生するようにしている)
<?php
namespace App\Exceptions;
use Exception;
use ErrorException;
use \Illuminate\Database\QueryException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
class Handler extends ExceptionHandler
{
protected $dontReport = [];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
if ($exception instanceof QueryException
|| $exception instanceof \Swift_TransportException
|| $exception instanceof NotFoundHttpException
|| $exception instanceof MethodNotAllowedHttpException
|| $exception instanceof FatalThrowableError
|| $exception instanceof ErrorException) {
return response()->view( 'error', ['exception' => $exception]);
}
return parent::render($request, $exception);
}
}
###ログイン認証をミドルウェアに記述
ルーティングに記述することで、指定したアクションに遷移した際に認証処理を実施する
*ログイン前の機能用のログイン認証ミドルウェア
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class BeforeLoginMiddleware
{
public function handle($request, Closure $next)
{
if (Auth::check()) {
return redirect()->action('TaskController@index');
}
return $next($request);
}
}
<?php
use App\Http\Middleware\BeforeLoginMiddleware;
// ログイン前
Route::get('/', 'IndexController@index')->middleware(BeforeLoginMiddleware::class);
//・・・・・・・
#ポートフォリオの課題
・ログイン処理がなくともメイン機能を見られるようにする(ポートフォリオとして簡単に確認できるようにする)
・完了、復元、編集処理後に検索条件の保持はできているが、ページングの保持ができていない。
・タスクの期限、通知機能の追加
・URLのhttps化
・make:authにて自動でユーザー情報周りの機能を実装
・モデルにスコープをつける(whereなどはコントローラに記述しない)
・DBにindexを設定(マイグレーションに実装)
・完了、復元機能の処理が重い
→ DB情報をキャッシュに格納して使用する。
→ Ajaxを使用
→ jQueryまたはVue.jsなどを用いてDOMの入れ替えのみをする。など
#現在の学習内容(2019.06.07現在)
・JavaScriptの基礎
・React、Vue.js(主にVue.js)
・Linuxの環境構築(ローカルの自分の端末上にて。シェルスクリプトを触るくらいを目指す)