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

ds_one's avatar

Custom FormRequest validation without DI

I am aware of custom FormRequests and can work with them just fine. But my question would be, is there any way where you can invoke such a form request validation manually inside a controller function without changing the $request paramater to said FormRequest?

Instead of

public function myFuncA(MyCustomRequestForInsuranceA $request) {
	// ...
}

for each and every claim with routes like

POST api/v1/insurance-claim/insuranceA -> MyClass::myFuncA
POST api/v1/insurance-claim/insuranceB -> MyClass::myFuncB
POST api/v1/insurance-claim/insuranceC -> MyClass::myFuncC
POST api/v1/insurance-claim/insuranceD -> MyClass::myFuncD

Something like

public function myFunc(Request $request, string $insuranceIdentifier) {
	switch ($insuranceIdentifier) {
		case "XY":
			$valid = Validator::validate($request->all(), MyCustomRequestForInsuranceXY::class);
		break;
		default: break;
	}
}

with routes like

POST api/v1/insurance-claim/{insuranceIdentifier} -> MyClass::myFunc

My goal would be to simply reduce the amount of fixed API routes and controller (entry) functions that I need. I tried looking into the Validator code but didn't find anything making sense and searched thoroughly via Google but can't seem to find anything regarding manually invoking a custom form request class on a $request without DI. Is that even possible?

Technically I could write all validation rules into one gigantic FormRequest class and distinguish with $insuranceIdentifier there but I'd prefer one FormRequest class per claim to keep it maintainable.

0 likes
8 replies
ds_one's avatar

Yes, I am aware of those docs, but they do not mention the custom FormRequest instance and that is my issue.

The code example is:

$validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

How do I get my CustomFormRequest in there without using DI? That's the question.

I could get the rules() from my CustomFormRequest via app(MyCustomRequest::class)->rules(), not knowing if this is the right approach. BUT it doesn't return the sometimes() conditions that are defined inside CustomFormRequest->validator() but I cannot invoke that function instead of rules() as I need to provide a factory parameter and I do not know what that is.

What I need to achieve in some way is this:

$validator = Validator::make($request->all(), CustomFormRequest::class);
if ($validator->fails()) {
	
}

The docs do not mention that or I am blind. Did I missing something there?

laracoft's avatar

@ds_one

rules() are usually just

    public function rules()
    {
        return [
            'email' => 'required|email|unique:users',
            'name' => 'required|string|max:50',
            'password' => 'required'
        ];
    }

It is odd that yours somehow strips out sometimes condition. Are you sure they are specified in the custom request class?

You can convert to a custom form request this way, try

$CustomFormRequest = CustomFormRequest::createFrom($request);
if ($CustomFormRequest->getValidatorInstance()->fails()) {
    ...
}
2 likes
ds_one's avatar

I wasn't aware of the casting of requests to other types of requests like this. That's neat, thanks! However, getValidatorInstance()is a protected function and I cannot call it in my Controller. Overwriting it in my CustomFormRequest to make it public and returning parent::getValidatorInstance() as well as simply returning$this->validator yields no results. The latter is empty, the former complains about Call to a member function make() on null inside FormRequest.php which is the line $factory = $this->container->make(ValidationFactory::class);.

My sometimes conditions are defined in the validator function not the rule array:

public function validator(Factory $factory) {
	$validator = $factory->make($this->input(), $this->rules(), $this->messages());

	$validator->sometimes('request_variable', 'required|numeric', function($input) {
		return $input->conditionXY == true;
	});

	// ...
}

when I tried to simply load the ->rules() from my CustomFormRequest these sometimes conditions were never triggered, which makes sense considering the rules function is called and not the validator function. I'd have to convert the sometimes rules in the rules array, like described here: https://laravel.com/docs/8.x/validation#conditionally-adding-rules

Perhaps then it works as intended. That means converting a dozen form requests, kinda limiting the usage of custom form requests to the rules() function. Hm.

Snapey's avatar

Why can you not do the switch in the request class?

The rules() method returns an array. That does not need to be all it does.

The returned rules array can be built on the fly based on other aspects of the request.

ds_one's avatar

@snapey That would mean I have a single gigantic god object dealing with the validation of a dozen similarish but quite different form requests where I'd put a couple dozen if conditions to build up the needed validation rules. Frankly, that doesn't sound maintainable nor like a good approach at all to me. Hence the attempt at dynamically applying different CustomFormRequests to the incoming request.

@laracoft Yes, that's the approach I am going for now, after moving the sometime definitions accordingly. Thanks for pushing me in the right direction!

laracoft's avatar

@ds_one glad you are moving forward. Do pick an answer that helped you best. Thank you.

Please or to participate in this conversation.