Php 在Laravel 5中扩展请求类

Php 在Laravel 5中扩展请求类,php,laravel,laravel-5,Php,Laravel,Laravel 5,我是拉雷维尔的新手(只有经验丰富的拉雷维尔5,所以这里没有遗留问题) 我想知道如何扩展核心请求类。除了如何扩展它,我还想知道这样做是否是一个明智的设计决策 我已经广泛地阅读了文档(特别是关于注册服务提供商以及它提供Facades访问依赖项容器中条目的方式),但是我可以看到(并找到)无法用我自己的实例替换\illumb\Http\Request实例以下是官方文档: app/Http/CustomRequest.php的内容 <?php namespace App\Http; use Ill

我是拉雷维尔的新手(只有经验丰富的拉雷维尔5,所以这里没有遗留问题)

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


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

以下是官方文档:

app/Http/CustomRequest.php的内容

<?php namespace App\Http;

use Illuminate\Http\Request as BaseRequest;

class CustomRequest extends BaseRequest {
    // coding
}
之后

更改public/index.php上的代码

$app->alias('request', 'App\Http\CustomRequest');
Illuminate\Http\Request::capture()
Illuminate\Http\Request::capture()


我今天在处理同一个问题,我认为值得一提的是,你可能会改变

不加线

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

因为在
capture()
方法中,laravel实际上使用'request'作为键将提供的类绑定到服务容器

我猜您还必须扩展
RequestForm
。我使用trait来避免代码重复。以下代码与Laravel 5.3相关

app/Http/ExtendRequestTrait.php

<?php
namespace App\Http\ExtendRequestTrait;

trait ExtendRequestTrait {
  methodFoo(){}
  methodBar(){}
}
<?php
namespace App\Http;
use Illuminate\Http\Request as BaseRequest;

class Request extend BasicRequest {
  use ExtendRequestTrait;
}
<?php
namespace App\Http;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;

class FormRequest extend BasicFormRequest {
  use ExtendRequestTrait;
}
<?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;
    }

}
app/Http/FormRequest.php

<?php
namespace App\Http\ExtendRequestTrait;

trait ExtendRequestTrait {
  methodFoo(){}
  methodBar(){}
}
<?php
namespace App\Http;
use Illuminate\Http\Request as BaseRequest;

class Request extend BasicRequest {
  use ExtendRequestTrait;
}
<?php
namespace App\Http;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;

class FormRequest extend BasicFormRequest {
  use ExtendRequestTrait;
}
<?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;
    }

}

不要忘了在
public/index.php
文件中将
light\Http\Request::capture()
切换到
App\Http\Request::capture()
,并添加
$App->alias('Request','App\Http\Request')
之后或内部
$app=require_once uuu DIR_uuu./../bootstrap/app.php'

我能够使用Laravel5.5中的
FormRequest
添加自定义请求对象,如下所示

首先,只需创建
FormRequest

php artisan make:request MyRequest

然后让它看起来像这样:

<?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 [
            //
        ];
    }
}
我确实意识到,
FormRequest
s实际上是用于不同的目的,但不管什么都可以


关于
FormRequest

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

<?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();
    }
}

在Laravel 5.5.x中,我能够使用以下方法扩展特定请求的请求类:

扩展请求类

<?php declare(strict_types = 1);

namespace App\Http\Request;

use Illuminate\Http\Request;

class ExtendedRequest extends Request {
    public function hello() {
        echo 'hello world!';
    }
}

你想完成什么?你为什么要用你自己的取而代之?我正在GH atm上做一个包裹。您可以从自述文件中看到,他们已经定义了自己的请求,但是有太多的冗余代码,他们用来自核心请求的信息填充它。实际上,通过更新index.php中的请求intance,我可以让它工作得很好,但这感觉不正确。此外,它不适用于单元测试。我认为这取决于您试图覆盖的方法,例如json方法。您可以扩展
illighted\Http\Request
并创建传真机<代码>$app->alias('request','app\Http\CustomRequest')是必需的!!!如果省略,例如,POST参数将不会出现在App\Http\CustomRequest对象中,但如果您希望对特定控制器使用自定义请求,则旧的Illumb\Http\Request。谢谢(顺便说一句:我不必在我的应用程序中添加
$app->alias('request','app\Http\CustomRequest');
)我认为从5.x开始,我的想法是扩展抽象类
app/Http/Requests/request.php
。我想这是为了方便。这可能是错误的。这是可行的,但我只需要为指定的控制器扩展请求,而不是为所有控制器扩展请求,但这样做,我在所有控制器中都得到扩展请求,即使我键入基本请求。一些想法?要仅扩展对特定控制器或特定功能的请求,请看我的答案。不错,但只有当您直接在控制器/服务/等中使用请求时才有效。如果您的自定义版本应该是父级,则不会使用。示例:FormRequest仍将使用原始请求。这对于Laravel 5.4是否仍然准确?在我的功能/集成测试中,我请求的$content似乎是空的。感谢您的评论,帮助我让测试正常工作,您可以从
vendor/laravel/framework/src/illighted/Foundation/Testing/Concerns/MakesHttpRequests.php中复制调用方法,因为它在laravel的从不版本中略有不同。在一些罕见的情况下,这也不起作用,因此我创建了一个函数来根据请求创建我的请求类受保护的静态函数getBaseRequest(){$request=request();if(是一个($request\light\Http\request::class)){return BaseRequest::createFrom($request);}return$request;}``这就是问题所在。这些都是为了处理表单请求,因此在其中添加任何其他类型的功能都会造成可怕的混乱。相信我。如果可能的话,最好扩展原始请求并添加附加功能。
<?php

namespace App\Http\Controllers;

use App\Http\Requests\PaginatedRequest;

class MyController
{
    public function __invoke(PaginatedRequest $request)
    {
        $request->page();
        // ...
    }
}
<?php declare(strict_types = 1);

namespace App\Http\Request;

use Illuminate\Http\Request;

class ExtendedRequest extends Request {
    public function hello() {
        echo 'hello world!';
    }
}
<?php declare(strict_types = 1);

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Http\Request\ExtendedRequest;

class ExtendedRequestServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(ExtendedRequest::class, function ($app) {
            return ExtendedRequest::capture();
        });
    }
}
<?php

namespace App\Controllers;

use App\Http\Request\ExtendedRequest;

class TestController extends Controller
{
    public function get(ExtendedRequest $request) {
        echo $request->hello();
    }
}