我是Laravel的新手(只有经验丰富的Laravel 5,所以这里没有遗留问题)
我想知道如何扩展核心Request类。除了如何扩展它之外,我想知道这样做是否是一个明智的设计决定。
我已经详细阅读了文档(特别是关于注册服务提供者以及它提供Facade访问依赖容器中条目的方式) - 但我可以看到(并找到)无法替换{ {1}}我自己的实例
答案 0 :(得分:26)
以下是正式文件:Request Lifecycle
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');
后
app = require_once __DIR__.'/../bootstrap/app.php';
更改public / index.php
中的代码Illuminate\Http\Request::capture()
到
App\Http\CustomRequest::capture()
答案 1 :(得分:3)
我想你还必须延长RequestForm
。我使用trait来避免代码重复。以下代码与 Laravel 5.3 相关。
app/Http/ExtendRequestTrait.php
<?php
namespace App\Http\ExtendRequestTrait;
trait ExtendRequestTrait {
methodFoo(){}
methodBar(){}
}
app/Http/Request.php
<?php
namespace App\Http;
use Illuminate\Http\Request as BaseRequest;
class Request extend BasicRequest {
use ExtendRequestTrait;
}
app/Http/FormRequest.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;
class FormRequest extend BasicFormRequest {
use ExtendRequestTrait;
}
对于phpunit测试工作,您必须覆盖call
方法,使其在Request
使用Request::create
类。
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;
}
}
并且不要忘记在Illuminate\Http\Request::capture()
文件中将App\Http\Request::capture()
切换为public/index.php
,并在$app->alias('request', 'App\Http\Request');
之后或之内添加$app = require_once __DIR__.'/../bootstrap/app.php';
答案 2 :(得分:2)
我今天正在处理同样的问题,我认为值得一提的是你可能只是改变
Illuminate\Http\Request::capture()
到
App\Http\CustomRequest::capture()
不添加行
$app->alias('request', 'App\Http\CustomRequest');
因为在capture()
方法中,laravel实际上将提供的类绑定到服务容器,并且请求&#39;作为关键
答案 3 :(得分:1)
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();
}
}
然后,我还必须在/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);
});
}
}
现在,仅在需要时,我才可以将PaginatedRequest注入我的控制器方法中
<?php
namespace App\Http\Controllers;
use App\Http\Requests\PaginatedRequest;
class MyController
{
public function __invoke(PaginatedRequest $request)
{
$request->page();
// ...
}
}
答案 4 :(得分:0)
我能够在Laravel 5.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 [
//
];
}
}
然后,您可以在MyRequest
作为参数的任何函数中使用Request
作为替代品:
public function get(MyRequest $request)
{
}
我确实认识到FormRequest
实际上是用于不同的目的,但无论如何都有效。
FormRequest
上的文档:https://laravel.com/docs/5.0/validation#form-request-validation
答案 5 :(得分:0)
在Laravel 5.5.x中,我可以使用以下命令扩展特定请求的Request类:
ExtendedRequest类
<?php declare(strict_types = 1);
namespace App\Http\Request;
use Illuminate\Http\Request;
class ExtendedRequest extends Request {
public function hello() {
echo 'hello world!';
}
}
ExtendedRequestServiceProvider
<?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();
}
}
希望这对某人有帮助。