Skip to content

laravel 中合并控制器的多个表单请求为一个的解决方案 #52

@guanguans

Description

@guanguans

laravel 中合并控制器的多个表单请求为一个的解决方案

laravel 中一个动作(action)方法需要对应编写一个表单请求(FormRequest)类。因此经常懒的去编写表单请求,而是直接在动作中编写验证规则。所以我扩展了表单请求基类,可方便的使一个控制器共用同一个表单请求类。

扩展之后的表单请求基类(app/Http/Requests/FormRequest)

<?php

namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Illuminate\Contracts\Validation\Validator;
use InvalidArgumentException;

class FormRequest extends \Illuminate\Foundation\Http\FormRequest
{
    /**
     * 指示验证是否应在第一个规则失败后停止。
     *
     * @var bool
     */
    protected $stopOnFirstFailure = true;

    public function validationData()
    {
        return $this->call(__FUNCTION__, $args = func_get_args(), parent::{__FUNCTION__}(...$args));
    }

    public function authorize(): bool
    {
        return $this->call(__FUNCTION__, func_get_args(), true);
    }

    public function rules(): array
    {
        return $this->call(__FUNCTION__, func_get_args(), []);
    }

    public function messages(): array
    {
        return $this->call(__FUNCTION__, $args = func_get_args(), parent::{__FUNCTION__}(...$args));
    }

    public function attributes(): array
    {
        return $this->call(__FUNCTION__, $args = func_get_args(), parent::{__FUNCTION__}(...$args));
    }

    protected function failedValidation(Validator $validator)
    {
        return $this->call(__FUNCTION__, $args = func_get_args(), parent::{__FUNCTION__}(...$args));
    }

    protected function failedAuthorization()
    {
        return $this->call(__FUNCTION__, $args = func_get_args(), parent::{__FUNCTION__}(...$args));
    }

    public function validator(ValidationFactory $factory): Validator
    {
        return $this->call(__FUNCTION__, func_get_args(), $this->createDefaultValidator($factory));
    }

    protected function withValidator(Validator $validator): Validator
    {
        return $this->call(__FUNCTION__, func_get_args(), $validator);
    }

    /**
     * @return callable|string
     */
    protected function after()
    {
        return $this->call(
            __FUNCTION__,
            func_get_args(),
            /**
             * @return mixed
             *
             * @throws \Throwable
             */
            static function (Validator $validator) {
                return $validator;
            }
        );
    }

    protected function call(string $method, array $args = [], $defaultReturn = null)
    {
        $actionMethod = transform($method, function (string $method) {
            if (! in_array(
                $method,
                [
                    'validationData',
                    'authorize',
                    'rules',
                    'messages',
                    'attributes',
                    'failedValidation',
                    'failedAuthorization',
                    'validator',
                    'withValidator',
                    'after',
                ],
                true
            )) {
                throw new InvalidArgumentException("Can't call the method[$method].");
            }

            return $this->route()?->getActionMethod().ucfirst($method);
        });

        if (method_exists($this, $actionMethod)) {
            return $this->$actionMethod(...$args);
        }

        if (method_exists(parent::class, $method)) {
            return parent::$method(...$args);
        }

        return $defaultReturn;
    }
}

使用示例

认证表单请求

<?php

namespace App\Http\Requests\Api;

use App\Http\Requests\FormRequest;

class AuthRequest extends FormRequest
{
    public function registerRules()
    {
        return [
            'email' => 'required|email|unique:App\Models\JWTUser,email',
            'password' => 'required|string|min:8|confirmed',
            'password_confirmation' => 'required|same:password',
        ];
    }

    public function loginRules()
    {
        return [
            'email' => 'required|email',
            'password' => 'required|string|min:8|confirmed',
        ];
    }
}

认证控制器

<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\AuthRequest;

class AuthController extends Controller
{
    public function register(AuthRequest $request)
    {
        $validated = $request->validated();
		...
    }

    public function login(AuthRequest $request)
    {
        $validated = $request->validated();
		...
    }
}

原文链接

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions