Laravel 形成 returns "The given data is invalid" 而我发送替代错误消息

Laravel form returns "The given data is invalid" while I send alternative error messages

我正在一个项目中使用 Laravel 6(包含在这个聊天系统/项目中)。 第一次如此寻找一些东西。 使用带有 PHPStorm 的 xdebug 的调试功能,我可以完美地遵循它。 这是我看到的:

注册控制器:

    protected function validator(array $data)
{
    $data['name'] = htmlspecialchars($data['name']);

    return Validator::make($data, [
        'name'     => ['required', 'string', 'max:100'],
        'email'    => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
        'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
        'min18years' => ['accepted'],
        'accept_all_agreements' => ['accepted'],
        'medical1' => ['accepted'],
        'medical2' => ['accepted']
    ], [
        'name.required' => 'A name is required',
        'email.required' => 'An email is required',
        'password.required' => 'A password is required',
        'min18years.accepted' => 'An approval for min 18 years is required',
        'accept_all_agreements.accepted' => 'An approval for agreements is required',
        'medical1.accepted' => 'An approval for medical1 is required',
        'medical2.accepted' => 'An approval for medical2 is required'
    ]);
}

$Data(来自调试器,故意未选中 min18years 复选框):

$data = {array} [9]
 _token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
 name = "Peter7"
 email = "my7@email.here"
 password = "123"
 password_confirmation = "123"
 min18years = "0"
 accept_all_agreements = "yes"
 medical1 = "yes"
 medical2 = "yes"

Illuminate\Validation\Validator.php:"

    public function validate()
{
    if ($this->fails()) {
        throw new ValidationException($this);
    }

    return $this->validated();
}

get抛出错误,调用“ValidationException”时的当前数据:

$这个:

$this = {Illuminate\Validation\Validator} [27]
 translator = {Illuminate\Translation\Translator} [7]
 container = {Illuminate\Foundation\Application} [33]
 presenceVerifier = {Illuminate\Validation\DatabasePresenceVerifier} [2]
 failedRules = {array} [1]
  min18years = {array} [1]
   Accepted = {array} [0]
 excludeAttributes = {array} [0]
 messages = {Illuminate\Support\MessageBag} [2]
  messages = {array} [1]
   min18years = {array} [1]
    0 = "An approval for min 18 years is required"
  format = ":message"
 data = {array} [9]
  _token = "oEMQFjasGoex4MDiThonh8Vw0e5UbyQ5o7GTRAi8"
  name = "Peter7"
  email = "my7@email.here"
  password = "123"
  password_confirmation = "123"
  min18years = "0"
  accept_all_agreements = "yes"
  medical1 = "yes"
  medical2 = "yes"
 initialRules = {array} [7]
 rules = {array} [7]
 currentRule = "accepted"
 implicitAttributes = {array} [0]
 implicitAttributesFormatter = null
 distinctValues = {array} [0]
 after = {array} [0]
 customMessages = {array} [7]
  name.required = "A name is required"
  email.required = "An email is required"
  password.required = "A password is required"
  min18years.accepted = "An approval for min 18 years is required"
  accept_all_agreements.accepted = "An approval for agreements is required"
  medical1.accepted = "An approval for medical1 is required"
  medical2.accepted = "An approval for medical2 is required"

但是当我跟随对\Illuminate\Validation\ValidationException的调用时。php:

public function __construct($validator, $response = null, $errorBag = 'default')
{
    parent::__construct('The given data was invalid.');

    $this->response = $response;
    $this->errorBag = $errorBag;
    $this->validator = $validator;
}

$this 没有收到传递给该函数的消息。

$这个:

$this = {Illuminate\Validation\ValidationException} [12]
 validator = null
 response = null
 status = {int} 422
 errorBag = null
 redirectTo = null
 message = ""
 *Exception*string = ""
 code = {int} 0
 file = "C:\Sources\wachtweken.nl\vendor\laravel\framework\src\Illuminate\Validation\Validator.php"
 line = {int} 386
 *Exception*trace = {array} [44]
 *Exception*previous = null

我希望在执行调试步骤时可以清楚这一点...

按要求添加了验证器函数(但这是默认的:

   protected function validator(array $data)
    {
        $data['name'] = htmlspecialchars($data['name']);

        return Validator::make($data, [
            'name'     => ['required', 'string', 'max:100'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:users', 'regex:/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/'],
            'password' => ['required', 'string', 'min:3', 'max:30', 'confirmed', new NoSpaceContaine()],
            'min18years' => ['accepted'],
            'accept_all_agreements' => ['accepted'],
            'medical1' => ['accepted'],
            'medical2' => ['accepted']
        ], [
            'name.required' => 'A name is required',
            'email.required' => 'An email is required',
            'password.required' => 'A password is required',
            'min18years.accepted' => 'An approval for min 18 years is required',
            'accept_all_agreements.accepted' => 'An approval for agreements is required',
            'medical1.accepted' => 'An approval for medical1 is required',
            'medical2.accepted' => 'An approval for medical2 is required'
        ]);
    }

来自更深层控制器的完整代码:

Post论坛的功能在这里:

RegisterController.php:注册

   /**
     * @param  Request  $request
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function register(Request $request)
    {
        try {
            $this->validator($request->all())->validate();

            event(new Registered($user = $this->create($request->all())));

            $this->guard()->login($user);

            return $this->registered($request, $user)
                ?: redirect($this->redirectPath());
        } catch (Exception $e) {
            return Redirect::back()->withInput()->withErrors(['error' => $e->getMessage()]);
        }
    }

Illuminate\Validation\Factory

        class Validator {
                    /**
         * Create a new Validator instance.
         *
         * @param array $data
         * @param array $rules
         * @param array $messages
         * @param array $customAttributes
         * @return \Illuminate\Validation\Validator 
         * @static 
         */ 
        public static function make($data, $rules, $messages = [], $customAttributes = [])
        {
                        /** @var \Illuminate\Validation\Factory $instance */
                        return $instance->make($data, $rules, $messages, $customAttributes);
        }
                    /**
         * Validate the given data against the provided rules.
         *
         * @param array $data
         * @param array $rules
         * @param array $messages
         * @param array $customAttributes
         * @return array 
         * @throws \Illuminate\Validation\ValidationException
         * @static 
         */ 
        public static function validate($data, $rules, $messages = [], $customAttributes = [])
        {
                        /** @var \Illuminate\Validation\Factory $instance */
                        return $instance->validate($data, $rules, $messages, $customAttributes);
        }
                    /**
         * Register a custom validator extension.
         *
         * @param string $rule
         * @param \Closure|string $extension
         * @param string|null $message
         * @return void 
         * @static 
         */ 

异常是触发器,它转到 Illuminate\Validation\ValidationException:

<?php

namespace Illuminate\Validation;

use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator as ValidatorFacade;

class ValidationException extends Exception
{
    /**
     * The validator instance.
     *
     * @var \Illuminate\Contracts\Validation\Validator
     */
    public $validator;

    /**
     * The recommended response to send to the client.
     *
     * @var \Symfony\Component\HttpFoundation\Response|null
     */
    public $response;

    /**
     * The status code to use for the response.
     *
     * @var int
     */
    public $status = 422;

    /**
     * The name of the error bag.
     *
     * @var string
     */
    public $errorBag;

    /**
     * The path the client should be redirected to.
     *
     * @var string
     */
    public $redirectTo;

    /**
     * Create a new exception instance.
     *
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
     * @param  \Symfony\Component\HttpFoundation\Response|null  $response
     * @param  string  $errorBag
     * @return void
     */
    public function __construct($validator, $response = null, $errorBag = 'default')
    {
        parent::__construct('The given data was invalid.');

        $this->response = $response;
        $this->errorBag = $errorBag;
        $this->validator = $validator;
    }

    /**
     * Create a new validation exception from a plain array of messages.
     *
     * @param  array  $messages
     * @return static
     */
    public static function withMessages(array $messages)
    {
        return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) {
            foreach ($messages as $key => $value) {
                foreach (Arr::wrap($value) as $message) {
                    $validator->errors()->add($key, $message);
                }
            }
        }));
    }

    /**
     * Get all of the validation error messages.
     *
     * @return array
     */
    public function errors()
    {
        return $this->validator->errors()->messages();
    }

    /**
     * Set the HTTP status code to be used for the response.
     *
     * @param  int  $status
     * @return $this
     */
    public function status($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Set the error bag on the exception.
     *
     * @param  string  $errorBag
     * @return $this
     */
    public function errorBag($errorBag)
    {
        $this->errorBag = $errorBag;

        return $this;
    }

    /**
     * Set the URL to redirect to on a validation error.
     *
     * @param  string  $url
     * @return $this
     */
    public function redirectTo($url)
    {
        $this->redirectTo = $url;

        return $this;
    }

    /**
     * Get the underlying response instance.
     *
     * @return \Symfony\Component\HttpFoundation\Response|null
     */
    public function getResponse()
    {
        return $this->response;
    }
}

你的问题是try/catch。您不必使用它,如果它抛出错误,它将默认 return 返回到它来自的页面 (response()->back()) 输入 (->withInput()) 和验证错误(errors 将被填充以供您在 blade 中使用)。

因此,将您的代码更改为:

public function register(Request $request)
{
    $this->validator($request->all())->validate();

    event(new Registered($user = $this->create($request->all())));

    $this->guard()->login($user);

    return $this->registered($request, $user)
        ?: redirect($this->redirectPath());
}

再次阅读 this 部分文档,您会发现这会起作用。