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

Chron's avatar

How to have conditional validation in Form Requests?

I have a field that accepts images. But if the image validation failed, I want it to go to CustomRule and test the input there. Otherwise, throw an error.

I want it to be like this

// UpdateUploaderRequest.php

use App\Rules\CustomRule;

public function rules(): array {
	
	return [
		'images' => 'required|array',
		'images.*' => 'image' || new CustomRule,
	];
}
1 like
10 replies
vincent15000's avatar

I do like this.

public function rules(): array
{
	$rules = [];
	
	$rules['images'] = 'required|array';

	if ($condition === true) {
		$rules['images.*'] = 'image';
	} else {
		$rules['images.*'] = new CustomRule;
	}

	return $rules;
}
2 likes
Snapey's avatar

You can use the regular validation rules inside your custom validator.

So I would mode the image rule there and then you can control the OR behaviour

4 likes
Chron's avatar

How can I access the validation rules inside custom validator?

//inside custom rule

public function validate(string $attribute, mixed $value, Closure $fail): void {
	if($condition) {
			$rules['images.*'] = "other rules";		
	} else {
			$rules['images.*'] = 'image|dimensions...''
	}
}
1 like
Chron's avatar

I think I'm doing it wrong. 🤔

I tried doing it and it passes the validation even though it shouldn't.

public function validate(string $attribute, mixed $value, Closure $fail): void
{
	$rules = $this->validator->getRules();
	$rules[$attribute] = ['string'];

	// $rules['images.0'] = ['string'];
}
1 like
Chron's avatar

if its not valid image, why on earth you're trying to continue?

I want it to accept either an image file or a file path (/uploads/image123.jpg). If the field only includes a file path, it skips the file upload/storing. In that way, it saves bandwidth.

//Controller

if($request->has('images')) {
	// $image->store...
}
1 like
Chron's avatar

I don't know if it helps but I'm using Vue/Inertiajs with Dropzonejs.


const form = useForm('patch', route('...', props.data.slug), {
	//...
	'images' : [],
});

onMounted(() => {
	const dropz = new Dropzone(..., {});
	dropz.on('addedfile', function(file) { form.images = this.files })
	dropz.on('removedfile', function(file) { form.images = this.files })
	if(prop.data.images.length) {
		//dropz.displayExistingFile(props.data.images)
	}
});

<div class="dropzone"></div>

That's true. when the user uploaded a file, it returns UploadedFile object. But when editing a resource, I don't want it to fetch the data then convert it to file and then add it. That could be an expensive task, that's why i only want to fetch the data from db then straight to adding it.

1 like
martinbean's avatar

@chron Well what does the “custom” rule actually do? Why you want to run any additional valuation rules if a prerequisite one (checking if the image is actually an image) has failed? What is there to validate if you already know the value isn’t valid?

3 likes
Chron's avatar

The custom rule just checks if that image, should be just a regular array when untouched, belongs to that entity.

1 like
martinbean's avatar

@chron I think you’re trying to combine too many different behaviours in a single field that it’s just going to be impossible to represent “nicely” when it comes to validation.

I want it to accept either an image file or a file path

Then have two separate fields. If a user can upload an image, give that input its own name. If a user can pick an existing image, then set the path in an input with a different name. Then validate the two. If you’re only expecting one of the other, make them mutually exclusive:

return [
    'image' => ['exclude_with:image_path', 'image'],
    'image_path' => ['exclude_with:image', 'string', 'exists:images,path'],
];

So if an image field is included, you validate it’s an uploaded file and a valid image, and you can then store it:

if ($image = $request->file('image')) {
    $path = $image->store('some-images-folder');
}

Otherwise, if an image_path field is included and not empty, you can do whatever you need to with the file path, knowing it’s also the path of a valid image in your database:

if ($path = $request->filled('image_path')) {
    // Do whatever with $path
}
2 likes

Please or to participate in this conversation.