在 Yii2 中使用 Laravel 验证类 
                                                    
                        
                    
                    
  
                    
                    下载 Laravel 验证类
composer require illuminate/validation:~5.6
创建 Validate 类
use Illuminate\Translation\FileLoader;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Translation\Translator;
use Illuminate\Validation\Factory;
use yii\web\Controller;
use yii\base\Action;
class Validate {
   protected $validator = null;
   //网上抄的代码,获取 Laravel  Validate 实例
   private function getValidator(){
        if(is_null($this->validator)){
            $test_translation_path = __DIR__ . '/lang';
            $test_translation_locale = 'en';
            $translation_file_loader = new FileLoader(new Filesystem, $test_translation_path);
            $translator = new Translator($translation_file_loader, $test_translation_locale);
            $this->validator = new Factory($translator);
        }
        return $this->validator;
   }
   // 使用反射获取控制器的验证规则
   private function getRuleClass(Controller $controller,Action $action){
        $reflection = new ReflectionClass($controller);
        $comment = $reflection->getMethod($action->actionMethod)->getDocComment();
        return Tools::getDocComment($comment, 'validator');
   }
   // 验证控制器规则
   public function check(Controller $controller, Action $action){
       $ruleClass = $this->getRuleClass($controller,$action);
       // 如果控制器没有验证规则,直接返回 true
       if(empty($rules) || !class_exists($validator)){
          return true;
       }
       $ruleClass = new $ruleClass;
       // 获取表单数据,GET + POST
       $request = \Yii::$app->request;
       $input = array_merge($request->get(), $request->post());
       $rules = $ruleClass->rules();
       $messages = $ruleClass->messages();
       $attributes = $ruleClass->attributes();
       $result = $this->getValidator()->make($input, $rules, $messages, $attributes);
       // 验证失败抛出 ValidateException
       if ($result->fails()) {
          throw new ValidateException($result->messages()->first());
       }
       return ture;
   }
}
Tools::getDocComment :
public static function getDocComment($comment, $tag)
{
    if (empty($tag)) {
        return $comment;
    }
    $matches = [];
    preg_match("/" . $tag . "(.*)(\\r\\n|\\r|\\n)/U", $comment, $matches);
    if (isset($matches[1])) {
        return trim($matches[1]);
    }
    return '';
}
创建抽象 RuleClass 类
abstract class ValidateRules{
    /**
     * 验证规则
      *
     * @return array
     * @see https://laravel-china.org/docs/laravel/5.6/validation/1372
     */
     abstract public function rules(): array;
     abstract public function messages(): array;
     abstract public function attributes(): array;
}
创建具体的验证规则
class UserAddRules extends ValidateRules{
    public function rules(){
        return [
             'username' => 'required|email',
             'password' => 'required'
        ];
    }
    public function messages(){
        return [
             'required' => ':attribute 不能为空',
             'email' => ':attribute 必须为邮箱格式'
        ];
    }
    public function attributes(){
        return [
            'username' => '用户名',
            'password' => '密码'
        ];
    }
}
在控制器中加入验证
class UserController extends BaseController {
    /**
     * @validator app\Validate\UserAddRules
     */
     public function actionAdd(){
     }
}
使用注解将验证规则加入到控制器上,@validator 填写包含命名空间的完整类名
在 BaseController 中全局验证
public function beforeAction($action)
{
    try {
      $validate = new Validate();
      $validate->check($this, $action);
    } catch (\ReflectionException $e) {
      $this->responseJson(Status::SERVER_ERROR, $e->getMessage());
      return false;
    } catch (ValidateException $e) {
      $this->responseJson(Status::BAD_REQUEST, $e->getMessage());
      return false;
    }
    return parent::beforeAction($action); 
}
结束语
之前在开发 Yii 应用时,发现框架自带验证是在数据入库时进行的验证,不太符合项目需求,然后通过搜索发现 Laravel 验证包可以单独使用,尝试一番,还是挺不错的,在 RuleClass 中的编写方式与 Laravel 中的 Request 类一致,只有个别需要数据库验证的( unique 等)不能使用,可以实现 Illuminate\Contracts\Validation\Rule 进行自定义规则。
本作品采用《CC 协议》,转载必须注明作者和本文链接
          
                    
                    
          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: