在 Laravel 5 中扩展请求类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30155500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:31:31  来源:igfitidea点击:

Extend Request class in Laravel 5

phplaravellaravel-5

提问by ninjapenguin

I'm new to Laravel (only experienced Laravel 5, so no legacy hang up here)

我是 Laravel 的新手(只体验过 Laravel 5,所以这里没有遗留问题)

I'd like to know how to extend the core Request class. In addition to how to extend it, i'd like to know if it's a wise design decision to do so.

我想知道如何扩展核心请求类。除了如何扩展它之外,我想知道这样做是否是一个明智的设计决定。

I've read through the documentation extensively (especially with regards to registering service providers and the manner in which it provides Facades access to entries within the dependency container) - but I can see (and find) no way to replace the \Illuminate\Http\Requestinstance with my own

我已经广泛阅读了文档(特别是关于注册服务提供者以及它提供对依赖容器中条目的 Facades 访问的方式) - 但我可以看到(并找到)无法\Illuminate\Http\Request用我自己的实例替换实例

回答by lne1030

Here is Official Document: Request Lifecycle

这是官方文档:请求生命周期

Content of app/Http/CustomRequest.php

app/Http/CustomRequest.php 的内容

<?php namespace App\Http;

use Illuminate\Http\Request as BaseRequest;

class CustomRequest extends BaseRequest {
    // coding
}

add this line to public/index.php

将此行添加到 public/index.php

$app->alias('request', 'App\Http\CustomRequest');

after

app = require_once __DIR__.'/../bootstrap/app.php';

change the code at public/index.php

更改 public/index.php 中的代码

Illuminate\Http\Request::capture()

to

App\Http\CustomRequest::capture()

回答by Александр Барсуков

I guess you will have to extend also RequestForm. I use trait to avoid code duplication. Code below is relevant for Laravel 5.3.

我想你也将不得不扩展RequestForm。我使用 trait 来避免代码重复。下面的代码与Laravel 5.3相关。

app/Http/ExtendRequestTrait.php

app/Http/ExtendRequestTrait.php

<?php
namespace App\Http\ExtendRequestTrait;

trait ExtendRequestTrait {
  methodFoo(){}
  methodBar(){}
}

app/Http/Request.php

app/Http/Request.php

<?php
namespace App\Http;
use Illuminate\Http\Request as BaseRequest;

class Request extend BasicRequest {
  use ExtendRequestTrait;
}

app/Http/FormRequest.php

app/Http/FormRequest.php

<?php
namespace App\Http;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;

class FormRequest extend BasicFormRequest {
  use ExtendRequestTrait;
}

For phpunit test working you will have to override callmethod to make it using right Requestclass here Request::create.

对于 phpunit 测试工作,您将必须覆盖call方法以使其Request在此处使用正确的类Request::create

test/TestCase.php

test/TestCase.php

<?php
use App\Http\Request;

abstract class TestCase extends Illuminate\Foundation\Testing\TestCase{

   // just copy Illuminate\Foundation\Testing\TestCase `call` method 
   // and set right Request class
   public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
    {
        $kernel = $this->app->make('Illuminate\Contracts\Http\Kernel');

        $this->currentUri = $this->prepareUrlForRequest($uri);

        $this->resetPageContext();

        $request = Request::create(
            $this->currentUri, $method, $parameters,
            $cookies, $files, 
            array_replace($this->serverVariables, $server), 
            $content
        );

        $response = $kernel->handle($request);

        $kernel->terminate($request, $response);

        return $this->response = $response;
    }

}

and don't forget to switch Illuminate\Http\Request::capture()to App\Http\Request::capture()in public/index.phpfile and to add $app->alias('request', 'App\Http\Request');after or inside $app = require_once __DIR__.'/../bootstrap/app.php';

不要忘记切换Illuminate\Http\Request::capture()App\Http\Request::capture()public/index.php文件,并添加$app->alias('request', 'App\Http\Request');后,或内$app = require_once __DIR__.'/../bootstrap/app.php';

回答by Egor

I was working on the same issue today and I think it's worth mention that you may just change

我今天正在研究同样的问题,我认为值得一提的是你可能会改变

Illuminate\Http\Request::capture()

to

App\Http\CustomRequest::capture()

without adding line

不加线

$app->alias('request', 'App\Http\CustomRequest');

because inside capture()method laravel actually binds provided class to service container with 'request' as a key

因为内部capture()方法 laravel 实际上将提供的类绑定到以“请求”为键的服务容器

回答by Pete McFarlane

Yerkes answer inspired me to write a custom class, for use with pagination, but only on specific requests

Yerkes 的回答启发我编写了一个自定义类,用于分页,但仅限于特定请求

<?php

namespace App\Http\Requests;

use Illuminate\Http\Request;

class PaginatedRequest extends Request
{
    public function page(): int
    {
        return max(1, (int) ($this['page'] ?? 1));
    }

    public function perPage(): int
    {
        $perPage = (int) ($this['per_page'] ?? 100);
        return max(1, min($perPage, 500));
    }

    public function offset(): int
    {
        return ($this->page() - 1) * $this->perPage();
    }
}

I then also had to register a new ServiceProvider in /config/app.php, which looks like

然后我还必须在 /config/app.php 中注册一个新的 ServiceProvider,它看起来像

<?php

namespace App\Providers;

use App\Http\Requests\PaginatedRequest;
use Illuminate\Support\ServiceProvider;

class PaginatedRequestServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->app->resolving(PaginatedRequest::class, function ($request, $app) {
            PaginatedRequest::createFrom($app['request'], $request);
        });
    }
}

Now I can simply inject the PaginatedRequest in my controller methods only when I need it

现在我可以简单地在我的控制器方法中注入 PaginatedRequest 仅在我需要它时

<?php

namespace App\Http\Controllers;

use App\Http\Requests\PaginatedRequest;

class MyController
{
    public function __invoke(PaginatedRequest $request)
    {
        $request->page();
        // ...
    }
}

回答by Yerke

I was able to add custom request object using FormRequestin Laravel 5.5 as follows.

我能够FormRequest在 Laravel 5.5 中添加自定义请求对象,如下所示。

First, just create FormRequest:

首先,只需创建FormRequest

php artisan make:request MyRequest

php artisan make:request MyRequest

Then just make it look like this:

然后让它看起来像这样:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MyRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

You can then use MyRequestas drop-in replacement in any function that takes Requestas parameter:

然后,您可以MyRequest在任何Request作为参数的函数中用作直接替换:

public function get(MyRequest $request)
{
}

I do realize that FormRequests are actually meant to be used for a different purpose, but whatever works.

我确实意识到FormRequests 实际上是为了用于不同的目的,但不管怎样都行。

Documentation on FormRequest: https://laravel.com/docs/5.0/validation#form-request-validation

文档FormRequesthttps: //laravel.com/docs/5.0/validation#form-request-validation