Jadual Kandungan
Laravel中使用FormRequest进行表单验证方法及问题汇总,laravelformrequest
Rumah pembangunan bahagian belakang tutorial php Laravel中使用FormRequest进行表单验证方法及问题汇总,laravelformrequest_PHP教程

Laravel中使用FormRequest进行表单验证方法及问题汇总,laravelformrequest_PHP教程

Jul 12, 2016 am 08:49 AM
laravel pengesahan borang

Laravel中使用FormRequest进行表单验证方法及问题汇总,laravelformrequest

在`Laravel`中,每一个请求都会被封装为一个`Request`对象,`Form Request`对象就是包含了额外验证逻辑(以及访问权限控制)的自定义`Request`类。 本文分析了FormRequest异常的处理流程并提出了自定义处理FormRequest验证失败的思路。

所有示例基于Laravel 5.1.39 (LTS)

今天天气不错,我们来说说表单验证。

Controller中做表单验证

有的同学把表单验证逻辑写在Controller中,例如这个对用户提交评论内容的验证:

<&#63;php

// ... 

use Validator;

class CommentController
{

  public function postStoreComment(Request $request)
  {
    $validator = Validator::make($request->all(), [
      'comment' => 'required', // 只是实例,就写个简单的规则,你的网站要是这么写欢迎在评论里贴网址
    ]);

    if ($validator->fails()) {
      return redirect()
        ->back()
        ->withErrors($validator)
        ->withInput();
    }
  }

Salin selepas log masuk

这样写的话,表单验证和业务逻辑挤在一起,我们的Controller中就会有太多的代码,而且重复的验证规则基本也是复制粘贴。

我们可以利用Form Request来封装表单验证代码,从而精简Controller中的代码逻辑,使其专注于业务。而独立出去的表单验证逻辑甚至可以复用到其它请求中,例如修改评论。

什么是Form Request

在Laravel中,每一个请求都会被封装为一个Request对象,Form Request对象就是包含了额外验证逻辑(以及访问权限控制)的自定义Request类。

如何使用Form Request做表单验证

Laravel提供了生成Form Request的Artisan命令:

$ php artisan make:request StoreCommentRequest

于是就生成了app/Http/Requests/StoreCommentRequest.php,让我们来分析一下内容:

<&#63;php

namespace App\Http\Requests;

use App\Http\Requests\Request; // 可以看到,这个基类是在我们的项目中的,这意味着我们可以修改它

class StoreCommentRequest extends Request
{
  /**
   * Determine if the user is authorized to make this request.
   *
   * @return bool
   */
  public function authorize() // 这个方法可以用来控制访问权限,例如禁止未付费用户评论…
  {
    return false; // 注意!这里默认是false,记得改成true
  }

  /**
   * Get the validation rules that apply to the request.
   *
   * @return array
   */
  public function rules() // 这个方法返回验证规则数组,也就是Validator的验证规则
  {
    return [
      //
    ];
  }
}

Salin selepas log masuk

那么很容易,我们除了让authorize方法返回true之外,还得让rules方法返回我们的验证规则:

<&#63;php

// ...

  public function rules()
  {
    return [

    ];
  }

// ...

Salin selepas log masuk

接着修改我们的Controller:

<&#63;php

// ...

  // 之前:public function postStoreComment(Request $request)
  public function postStoreComment(\App\Http\Requests\StoreCommentRequest $request)
  {
    // ...
  }

// ...

Salin selepas log masuk

这样Laravel便会自动调用StoreCommentRequest进行表单验证了。

异常处理

如果表单验证失败,Laravel会重定向到之前的页面,并且将错误写到Session中,如果是AJAX请求,则会返回一段HTTP状态为422的JSON数据,类似这样:

{comment: ["The comment field is required."]}

这里就不细说提示信息怎么修改了,如果有人想看相关教程,可以留言。

我们主要来说说怎么定制错误处理。

通常来说,Laravel中的错误都是异常(Exception),我们都可以在app\Exceptions\handler.php中进行统一处理。Form Request确实也抛出了一个Illuminate\Http\Exception\HttpResponseException异常,但这个异常是在路由逻辑中就被特殊处理了。

首先我们来看看Form Request是如何被执行的:

Illuminate\Validation\ValidationServiceProvider:

<&#63;php

namespace Illuminate\Validation;

use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Validation\ValidatesWhenResolved;

class ValidationServiceProvider extends ServiceProvider
{
  /**
   * Register the service provider.
   *
   * @return void
   */
  public function register()
  {
    $this->registerValidationResolverHook(); // 看我看我看我

    $this->registerPresenceVerifier();

    $this->registerValidationFactory();
  }

  /**
   * Register the "ValidatesWhenResolved" container hook.
   *
   * @return void
   */
  protected function registerValidationResolverHook() // 对,就是我
  {
    // 这里可以看到对`ValidatesWhenResolved`的实现做了一个监听
    $this->app->afterResolving(function (ValidatesWhenResolved $resolved) {
      $resolved->validate(); // 然后调用了它的`validate`方法进行验证
    });
  }

// ...

Salin selepas log masuk

你猜对了,Form Request就实现了这个Illuminate\Contracts\Validation\ValidatesWhenResolved接口:

<&#63;php 

namespace Illuminate\Foundation\Http;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Container\Container;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exception\HttpResponseException;
use Illuminate\Validation\ValidatesWhenResolvedTrait;
use Illuminate\Contracts\Validation\ValidatesWhenResolved; // 是你
use Illuminate\Contracts\Validation\Factory as ValidationFactory;

// 我们`app\Http\Requests\Request`便是继承于这个`FormRequest`类
class FormRequest extends Request implements ValidatesWhenResolved // 就是你
{
  use ValidatesWhenResolvedTrait; // 这个我们待会儿也要看看

  // ...

Salin selepas log masuk

FormRequest基类中的validate方法是由这个Illuminate\Validation\ValidatesWhenResolvedTrait实现的:

Illuminate\Validation\ValidatesWhenResolvedTrait:

<&#63;php

namespace Illuminate\Validation;

use Illuminate\Contracts\Validation\ValidationException;
use Illuminate\Contracts\Validation\UnauthorizedException;

/**
 * Provides default implementation of ValidatesWhenResolved contract.
 */
trait ValidatesWhenResolvedTrait
{
  /**
   * Validate the class instance.
   *
   * @return void
   */
  public function validate() // 这里实现了`validate`方法
  {
    $instance = $this->getValidatorInstance(); // 这里获取了`Validator`实例

    if (! $this->passesAuthorization()) {
      $this->failedAuthorization(); // 这是调用了访问授权的失败处理
    } elseif (! $instance->passes()) {
      $this->failedValidation($instance); // 这里调用了验证失败的处理,我们主要看这里
    }
  }

  // ...

Salin selepas log masuk

在validate里,如果验证失败了就会调用$this->failedValidation(),继续:

Illuminate\Foundation\Http\FormRequest:

<&#63;php

// ...

  /**
   * Handle a failed validation attempt.
   *
   * @param \Illuminate\Contracts\Validation\Validator $validator
   * @return mixed
   */
  protected function failedValidation(Validator $validator)
  {
    throw new HttpResponseException($this->response( // 这里抛出了传说中的异常
      $this->formatErrors($validator)
    ));
  }

Salin selepas log masuk

终于看到异常了!可是这个异常在另一个地方被处理了:

Illuminate\Routing\Route:

<&#63;php

  // ...

  /**
   * Run the route action and return the response.
   *
   * @param \Illuminate\Http\Request $request
   * @return mixed
   */
  public function run(Request $request)
  {
    $this->container = $this->container &#63;: new Container;

    try {
      if (! is_string($this->action['uses'])) {
        return $this->runCallable($request);
      }

      if ($this->customDispatcherIsBound()) {
        return $this->runWithCustomDispatcher($request);
      }

      return $this->runController($request);
    } catch (HttpResponseException $e) { // 就是这里
      return $e->getResponse(); // 这里直接返回了Response给客户端
    }
  }

  // ...

Salin selepas log masuk

至此,整个思路已然清晰,不过我们还是看看这里生成的HttpResponseException异常中的Response是怎么生成的:

Illuminate\Foundation\Http\FormRequest:

<&#63;php

// ...

  // 132行:
  if ($this->ajax() || $this->wantsJson()) { // 对AJAX请求的处理
    return new JsonResponse($errors, 422);
  }

  return $this->redirector->to($this->getRedirectUrl()) // 对普通表单提交的处理
                  ->withInput($this->except($this->dontFlash))
                  ->withErrors($errors, $this->errorBag);

// ...

Salin selepas log masuk

相信你都看明白了。

如何实现自定义错误处理,这里提供两个思路,都需要重写app\Http\Requests\Request的failedValidation:

抛出一个新异常,继承HttpResponseException异常,重新实现getResponse方法,这个异常类我们可以放到app/Exceptions/下便于管理,错误返回依然交给Laravel;

抛出一个我们自定义的异常,在app\Exceptions\handler中处理。

具体实现这里就不写啦(参阅Laravel文档中关于错误处理部分,中文文档传送门),如果你有别的方法或者想法可以在评论中和我交流。

补充

如果你的Controller使用Illuminate\Foundation\Validation\ValidatesRequests这个Trait的validate方法进行验证,同样的,这里验证失败也会抛出Illuminate\Http\Exception\HttpResponseException异常,可以参考上面的解决方案进行处理。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1136626.htmlTechArticleLaravel中使用FormRequest进行表单验证方法及问题汇总,laravelformrequest 在`Laravel`中,每一个请求都会被封装为一个`Request`对象,`Form Request`对象...
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk mendapatkan kod pengembalian semasa menghantar e -mel gagal di Laravel? Bagaimana untuk mendapatkan kod pengembalian semasa menghantar e -mel gagal di Laravel? Apr 01, 2025 pm 02:45 PM

Kaedah untuk mendapatkan kod kembali apabila menghantar e -mel Laravel gagal. Apabila menggunakan Laravel untuk membangunkan aplikasi, anda sering menghadapi situasi di mana anda perlu menghantar kod pengesahan. Dan pada hakikatnya ...

Tugas Jadual Laravel tidak dilaksanakan: Apa yang harus saya lakukan jika tugas itu tidak berjalan selepas Jadual: Jalankan Perintah? Tugas Jadual Laravel tidak dilaksanakan: Apa yang harus saya lakukan jika tugas itu tidak berjalan selepas Jadual: Jalankan Perintah? Mar 31, 2025 pm 11:24 PM

Tugas Jadual Laravel menjalankan penyelesaian masalah yang tidak responsif semasa menggunakan penjadualan tugas jadual Laravel, banyak pemaju akan menghadapi masalah ini: Jadual: Jalankan ...

Di Laravel, bagaimana menangani situasi di mana kod pengesahan gagal dihantar melalui e -mel? Di Laravel, bagaimana menangani situasi di mana kod pengesahan gagal dihantar melalui e -mel? Mar 31, 2025 pm 11:48 PM

Kaedah mengendalikan kegagalan e -mel Laravel untuk menghantar kod pengesahan adalah menggunakan Laravel ...

Bagaimana untuk melaksanakan fungsi jadual tersuai untuk mengklik untuk menambah data dalam admin dcat? Bagaimana untuk melaksanakan fungsi jadual tersuai untuk mengklik untuk menambah data dalam admin dcat? Apr 01, 2025 am 07:09 AM

Cara melaksanakan fungsi jadual klik tersuai untuk menambah data dalam dcatadmin (laravel-admin) semasa menggunakan dcat ...

Laravel - Pelayan Buang Laravel - Pelayan Buang Aug 27, 2024 am 10:51 AM

Laravel - Dump Server - Laravel dump server datang dengan versi Laravel 5.7. Versi sebelumnya tidak termasuk pelayan dump. Pelayan dump akan menjadi kebergantungan pembangunan dalam fail komposer laravel/laravel.

Perkongsian Sambungan Laravel Redis: Mengapa kaedah pilih mempengaruhi sambungan lain? Perkongsian Sambungan Laravel Redis: Mengapa kaedah pilih mempengaruhi sambungan lain? Apr 01, 2025 am 07:45 AM

Kesan perkongsian sambungan Redis dalam rangka kerja Laravel dan pilih kaedah apabila menggunakan Rangka Kerja Laravel dan Redis, pemaju mungkin menghadapi masalah: melalui konfigurasi ...

Laravel Multi-Tenant Extension Stancl/Tenancy: Bagaimana Menyesuaikan Alamat Hos Sambungan Pangkalan Data Penyewa? Laravel Multi-Tenant Extension Stancl/Tenancy: Bagaimana Menyesuaikan Alamat Hos Sambungan Pangkalan Data Penyewa? Apr 01, 2025 am 09:09 AM

Sambungan pangkalan data penyewa tersuai dalam pakej lanjutan multi-penyewa Larave Stancl/penyewaan ketika membina aplikasi multi-penyewa menggunakan pakej lanjutan multi-penyewa Larave Stancl/penyewaan, ...

Laravel - URL Tindakan Laravel - URL Tindakan Aug 27, 2024 am 10:51 AM

Laravel - URL Tindakan - Laravel 5.7 memperkenalkan ciri baharu yang dipanggil &quot;URL tindakan boleh panggil&quot;. Ciri ini serupa dengan yang terdapat dalam Laravel 5.6 yang menerima kaedah rentetan dalam tindakan. Tujuan utama sintaks baharu memperkenalkan Laravel 5.7 adalah untuk mengarahkanl

See all articles