Extend Request class in Laravel 5

后端 未结 6 1387
猫巷女王i
猫巷女王i 2020-12-08 22:48

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

I\'d like to know how to extend the core Request class. In addition to how to extend it,

相关标签:
6条回答
  • 2020-12-08 22:53

    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

    0 讨论(0)
  • 2020-12-08 22:58

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

    <?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

    <?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

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Requests\PaginatedRequest;
    
    class MyController
    {
        public function __invoke(PaginatedRequest $request)
        {
            $request->page();
            // ...
        }
    }
    
    0 讨论(0)
  • 2020-12-08 23:10

    Here is Official Document: Request Lifecycle

    Content of 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

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

    after

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

    change the code at public/index.php

    Illuminate\Http\Request::capture()
    

    to

    App\Http\CustomRequest::capture()
    
    0 讨论(0)
  • 2020-12-08 23:17

    I guess you will have to extend also RequestForm. I use trait to avoid code duplication. Code below is relevant for 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;
    }
    

    For phpunit test working you will have to override call method to make it using right Request class here 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;
        }
    
    }
    

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

    0 讨论(0)
  • 2020-12-08 23:17

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

    First, just create FormRequest:

    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 MyRequest as drop-in replacement in any function that takes Request as parameter:

    public function get(MyRequest $request)
    {
    }
    

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

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

    0 讨论(0)
  • 2020-12-08 23:17

    In Laravel 5.5.x, I was able to extend the Request class for specific requests using the following:

    ExtendedRequest class

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

    Then in your Controllers

    <?php
    
    namespace App\Controllers;
    
    use App\Http\Request\ExtendedRequest;
    
    class TestController extends Controller
    {
        public function get(ExtendedRequest $request) {
            echo $request->hello();
        }
    }
    

    Hope this helps someone.

    0 讨论(0)
提交回复
热议问题