優雅建構 Validation Rule -- 使用 Rule 套件
前言
我一直認為 Laravel 在 Validation Rule 的設計上很怪異。
以下是一段 Controller 常見的程式碼(礙於篇幅,我省略了一些內容):
<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
public function postEmail($request)
{
$this->request($request, [
'email' => 'required|email|max:255|unique:users,'.Auth::user()->id,
]);
}
}
這種寫法有個壞處,就是當規則為「不定」的時候。
像是 unique 若要排除條件,或是 max 的值為不定值(可能因為其它因素造成該使會變動),這樣它的規則要動態變化其實寫起來就很醜。
於是,為了解決這樣的問題,再加上我剛好在學習怎麼學寫 Package ,我花了大概 3 個小時寫了一個 Rule 的套件來解決這樣的情況。
安裝方法
compsoer require chivincent/rule
在 config/app.php
的 providers
陣列中加入以下內容:
Chivincent\Rule\RuleServiceProvider::class
在 config/app.php
的 aliases
陣列中加入以下內容:
'Rule' => Chivincent\Rule\RuleFacade::class,
使用方法
不在 Controller 中:
<?php
namespace App\SomethingAwesome;
use ValidatorException;
use Validator;
use Rule;
class Awesome
{
public function pretty(array $contents)
{
$rule = [
'title' => Rule::required()->max(255)->unique('posts')->export();
];
$validator = Validator::make($contents, $rule);
if ($validator->fails)
throw new ValidatorException($validator);
}
}
在 Controller 中:
<?php
namespace App\Http\Controllers;
use Request;
class WelcomeController extends Controllers
{
public function getWelcome(Request $request)
{
$rule = [
'user' => Rule::required()->export(),
];
$this->validate($request, $rule);
}
}
APIs
允許的 Validtion 規則
其中,把所有的 method 從 snake case 改為 came case
'required' => required()
'required_if' => requiredIf()
這些會 return RuleMaker
實體
匯出規則
本套件允許匯出兩種格式:string
跟 array
export(): array
exportArray(): array
exportString(): string
<?php
use Rule;
$rule = Rule::required()->max(255);
$rule->export();
$rule->exportArray();
/**
* Array (
* '0' => 'required',
* '1' => 'max:255',
* )
*/
$rule->exportString()
/**
* 註:如果在 Validation 規則中有使用正則表達成(Regex),則無法匯出為 String,會丟出 CannotExportStringException
* String ("required|max:255")
*/
本文同步發表於 Chivincent's Blog