Laravel Validation rules: required_without
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Conditional Validation in Laravel: Moving Beyond required_without
As senior developers working with Laravel, we constantly encounter scenarios where validation isn't a simple binary check. We often need rules that depend on the presence or value of other fieldsâconditional validation. One common point of confusion arises when trying to achieve "if A exists, then B must be valid" logic using built-in methods like required_without.
This post dives deep into why your attempt with required_without might not have worked for your specific requirement and shows you the robust, developer-friendly patterns for handling complex, interdependent validation in Laravel.
The Pitfall of required_without
Let's first understand what the required_without rule does. It is designed purely for dependency checking: it ensures that if one field is missing, another must be present and valid.
In your scenarioâwhere you want to ensure that at least one of two fields (Email or Telephone) exists AND is correctly formattedârequired_without alone isn't sufficient because it only checks for necessity, not combined validity.
Your original attempt:
public static array $createValidationRules = [
'email' => 'required_without:telephone|email:rfc',
'telephone' => 'required_without:email|numeric|regex:/^\d{5,15}$/',
];This setup tells Laravel: "The email field is required unless the telephone field is present." This creates a dependency loop rather than checking if one or the other meets their individual format requirements when they are present.
The Correct Approach: Conditional Logic and Custom Rules
When validation logic becomes complex, relying solely on simple rules is often insufficient. The most robust solution involves moving the conditional decision-making into the controller layer or utilizing more advanced features like custom rule classes.
For your specific requirementâ"one of these must be present and correctly formatted"âwe need a system that checks combinations. Here are two effective methods:
Method 1: Conditional Logic in the Controller (The Practical Route)
Instead of trying to force complex logic into the validation rules array, it is often cleaner and more maintainable to let Laravel handle basic format validation, and use custom application logic for cross-field dependencies. This keeps your validation rules focused on what needs to be checked, not how those checks interact.
First, define the base rules:
// In your Request class or Controller setup
$rules = [
'email' => 'nullable|email', // Allow null initially if we handle it later
'telephone' => 'nullable|string',
];Then, implement the conditional check in your request handling:
use Illuminate\Http\Request;
class RegistrationRequest extends Request
{
public function rules()
{
$rules = [
'email' => 'nullable|email',
'telephone' => 'nullable|string',
];
// Apply base rules...
// Custom conditional check logic here:
if ($this->has('email') && !$this->has('telephone')) {
// If email is present but phone is absent, we might enforce a stricter rule if needed.
// For this case, we rely on the fact that both are optional unless business rules dictate otherwise.
}
return $rules;
}
public function handle()
{
$request->validate($this->rules());
// Example of custom validation post-check:
if ($request->has('email') || $request->has('telephone')) {
// Now, perform the combined check you need.
if (!$request->has('email') && !$request->has('telephone')) {
throw new \Illuminate\Validation\ValidationException::withMessages([
'error' => 'Either email or telephone must be provided.',
]);
}
}
}
}Method 2: Custom Rule Classes (The Advanced Route)
For truly complex, reusable business logic that needs to live within the validation layer, creating a custom rule is the professional approach. This keeps your request rules clean while centralizing the complex logic. This aligns perfectly with the philosophy of building scalable applications, much like handling data structures in Laravel makes development smooth on platforms like https://laravelcompany.com.
You would create a rule that checks if at least one field meets its specific criteria when both are present.
Conclusion
The journey from simple validation to conditional validation requires shifting perspective. Don't try to force complex relational logic into simple rules like required_without. Instead, separate concerns: use built-in rules for format checking, and leverage the power of your controller or custom validation rules to handle the interdependent business logic. By separating presentation (validation) from behavior (logic), you write code that is easier to test, debug, and maintain.