Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lcf8381595's avatar

[L5]how to use Form Validation Request Injection in a subclass

I have a base controller, which like below:

class AdminBaseController extends Controller {
     public function store(Request $request)
    {
    .........
    }
}

Then i have a subclass which extend above class and override the store function like below:

class AdminBlogsController extends AdminBaseController {
    public function store(StoreBlogPostRequest $request)
        {
        ........
    }
}

The function parameter StoreBlogPostRequest is a Form Validation Request class which I used to validate the post form.

but now I got the error lilke ErrorException in AdminBlogsController.php line 12: Declaration of App\Http\Controllers\Admin\AdminBlogsController::store() should be compatible with App\Http\Controllers\Admin\AdminBaseController::store(Illuminate\Http\Request $request)

so i guess the error is because two method have different type of parameter? how to fix that.

Thanks

0 likes
34 replies
RachidLaasri's avatar
class AdminBaseController extends Controller {
    public function store(FormRequest $request)
    {
        // Your code here
    }
}
lcf8381595's avatar

I tried to change "Request" to "FormRequest " , but still same error.

Declaration of App\Http\Controllers\Admin\AdminBlogsController::store() should be compatible with App\Http\Controllers\Admin\AdminBaseController::store(Illuminate\Foundation\Http\FormRequest $request)

RachidLaasri's avatar

can you show us the content of this class "StoreBlogPostRequest"

lcf8381595's avatar
<?php namespace App\Http\Requests;

class StoreBlogPostRequest extends Request  {

    /**
     * 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 [
            'title' => 'required',
            'body' => 'required',
            'thumb'=> 'required',
            'published_at'=>'required|date'
        ];
    }

}
lcf8381595's avatar

i used below command to generate this class.

php artisan make:request StoreBlogPostRequst
xingfucoder's avatar

Hi, the error told you:

App\Http\Controllers\Admin\AdminBlogsController::store()

Review your AdminBlogsController store method because seems to be that your AdminBlogsController hadn't any parameter when the error was sent.

xingfucoder's avatar

Hey, I have just view that you extend from AdminBaseSimpleController not AdminBaseController.

Review it.

lcf8381595's avatar

AdminBlogsController is looks like below:

class AdminBlogsController extends AdminBaseController {
     public function store(StoreBlogPostRequest $request)
        {
        //some code here.
    }
}
RachidLaasri's avatar

Try like this :

class AdminBaseController extends Controller {

    public function store(FormRequest $request)
    {
        //
    }

}
class AdminBlogsController extends AdminBaseController {

    public function store(StoreBlogPostRequest $request)
    {
        //
    }

}

You probably wrote the class name wrong, as @codeatbusiness mentioned.

lcf8381595's avatar

@RachidLaasri , my code is exactly same as yours. but still got the error.

Declaration of App\Http\Controllers\Admin\AdminBlogsController::store() should be compatible with App\Http\Controllers\Admin\AdminBaseController::store(Illuminate\Foundation\Http\FormRequest $request)

and i have checked the code many time, the class name is correct, it is

class AdminBlogsController extends AdminBaseController {
     public function store(StoreBlogPostRequest $request)
        {
        //
    }
}
xingfucoder's avatar

Hi @lcf8381595 did you use any namespace within your project and imported the AdminBaseController within your AdminBlogsController? You also need to import or use a backslash with your request and request subclass.

lcf8381595's avatar

@codeatbusiness i am using default APP as the namespace, AdminBaseController and AdminBlogsController are in same folder have same namespace, so do not need imported AdminBaseController to AdminBlogsController.

xingfucoder's avatar

How did you take the Request and StoreBlogPostRequest? Wich their namespaces are?

lcf8381595's avatar

StoreBlogPostRequest class

<?php namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreBlogPostRequest extends FormRequest  {
    //
}

AdminBaseController class

<?php namespace App\Http\Controllers\Admin;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Laracasts\Flash\Flash;
use Illuminate\Support\Facades\Redirect;

class AdminBaseController extends Controller {
 public function store(FormRequest $request)
    {
       //
    }
}

AdminBlogsController class

<?php namespace App\Http\Controllers\Admin;

use App\Blog;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreBlogPostRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Str;
use Laracasts\Flash\Flash;

class AdminBlogsController extends AdminBaseController {
     public function store(StoreBlogPostRequest $request)
        {
        //
    }
}
bestmomo's avatar

Does it work with :

class AdminBlogsController extends AdminBaseController {
     public function store(StoreBlogPostRequest $request = null)
        {
        //
    }
}
rieves's avatar

Why do you need to have a store method in the AdminBaseController?

nolros's avatar

@lcf8381595 Unsure what you are trying to do, but I think your problem is you attempting to extend a normal class i.e. AdminBaseController. Controller is abstract class you can extend that, if you want to extend AdminBaseController change it to abstract or just extend Controller.

lcf8381595's avatar

@nolros Thanks. let me explain what I am trying to do. AdminBaseController extend Controller, which have store method. some any class like AdminBlogController or AdminPostController extend AdminBaseController, so they all have their parent 's store method by default, so these subclass do not need write same store code in each of them.

But for one of the subclass like AdminPostController i do no want use the parent class AdminBaseController 's store method, i want override this method in this subclass. so i redefined the store() method in this subclass. and then cause the error..

I am sure then error means that store() method is sub class and parent class do not have same type of parameter. i am just not sure how to fix that. the parent class store method have one parameter which is Illuminate\Http\Request $request, and the subclass store method have one parameter which is App\Http\Requests\StoreBlogPostRequest ( used make:request to generate this class for validate the form post before store )

Thanks.

1 like
nolros's avatar

Have you tried this setup

// abstract classs
abstract AdminBaseController extend Controller

    public function store( StoreBlogPostRequest )
    {
        // code set 1
    }

class AdminBlogController extends AdminBaseController

    public function store ( StoreBlogPostRequest )
    {
        // code overwrite code
    }

class AdminPostController extends AdminBaseController

// no store method as it will inherit from AdminBaseController
lcf8381595's avatar

@nolros For AdminBaseController class store() method, i can not use StoreBlogPostRequest as the parameter, because all subclass will have different Validate Class. for example

AdminBlogController will have method store ( StoreBlogPostRequest ) AdminMovieController will have method store( StoreMoviePostRequest )

nolros's avatar

@lcf8381595 i think you are attempting inheritance but not really using it so I would suggest you use the same StoreBlogPostRequest request and build conditional logic logic inside the validation to filter. If that is not an option you could use route filters to direct to the right method and keep them separate. You can also build custom validators and store them in a ServiceProvider or your route file. I personally would not attempt what you are attempting as it flies in the face of inheritance but if you really want it to work you could attempt usman's suggestion.

rieves's avatar

You could just use a trait for classes that share a store method.

pmall's avatar

This can't be done ( http://stackoverflow.com/questions/19448742/override-interface-parent-method-that-use-type-hinting )

Child classes methods have to have exactly the same signatures. You have to change your structure.

I've already done this by injecting a FormRequestInterface to the method and binding it to the correct form request implementation according to the url / route.

class AdminBaseController extends Controller {
     public function store(FormRequestInterface $request)
    {
    .........
    }
}

class AdminBlogsController extends AdminBaseController {
    public function store(FormRequestInterface $request)
        {
        ........
    }
}
class AppServiceProvider{

  public register(Request $request, Route $route)
  {
    $route_name = $route->getCurrentRouteName() // Not sure of the syntax, don't remember

    if($route_name == 'admin.index') $this->app->bind('App\Http\Requests\FormRequestInterface', function() use($request)
    {
      return $request;
    });

    if($route_name == 'admin.blogs.index') $this->app->bind(
      'App\Http\Requests\FormRequestInterface',
      'App\Http\Requests\StoreBlogPostRequest'
    );
  }

}
2 likes
vincentveyrat's avatar

I went to the same issue.

Isn't it possible to make such a thing ?

class AdminBaseController extends Controller {
    protected $request;
    public function __construct()
    {
        \App::when( get_class() )
                  ->needs('Requests\FormRequestInterface')
                  ->give($this->request);
        
    }
     public function store(Requests\FormRequestInterface $request)
    {
    .........
    }
}
class AdminBlogsController extends AdminBaseController {
    protected $request = 'Requests\StoreBlogPostRequest';
}
pmall's avatar

It cant work like this. The method signature must be the same, here there is FormRequest in the parent class and StoreBlogpostRequest on the child class.

Create an interface for your form request. For example AdminFormRequestInterface. So the signature can be the same for all the admin controllers.

Then, in your AppServiceProvider, you have to detect when the request is for a blog (it can be determined from the request url for example). Then, if the request id for a blog, you can bind the AdminFormRequestInterface to StoreBlogPostRequest, so it is the one which will be injected. You may also use contextual binding to achieve this. The point is, use AppServiceProvider to bind the interface to its correct implementation someway and it is done.

By the way, I don't see the point of extending a parent controller.

Edit i didn't notice I've already answered this above ^^

Really, what is the point of extending a controller ?

vincentveyrat's avatar

Ok, merci @pmall !

When you have to make a CRUD for a lot of Model, extending a controller is really useful because you don't have to re-invent the wheel for every model. You only need to re-use the common resource base controller which already implement the controller's methods, kind of Don't Repeat Yourself if you will. I'd be glad to use the auto-magical Requests but I'll keeps my old Validators instead ;)

pmall's avatar

When you have to make a CRUD for a lot of Model, extending a controller is really useful because you don't have to re-invent the wheel for every model.

Yes but with model / request injection you don't even need to have many controllers, only one is enough.

Next

Please or to participate in this conversation.