Laravel is a powerful PHP framework known for its elegant syntax and robust features. One such feature introduced in Laravel 11.35.0 is the when()
and unless()
methods, part of the Conditionable
trait. These methods provide a more readable, efficient way to handle conditional logic, improving the maintainability of your code. In this article, we’ll explore how to use these methods in real-life scenarios, demonstrating how they can streamline complex conditional logic in Laravel applications.
1. Dynamic Role Assignment Based on User Input
Imagine you’re building a user registration form where the user selects a role. Depending on the role, you want to assign different permissions or actions after creating the user.
Without when()
:
if ($request->has('role')) {
$user->assignRole($request->input('role'));
}
With when()
:
$user->when($request->has('role'), function ($user) use ($request) {
$user->assignRole($request->input('role'));
});
In this case, we only assign a role if the role input is present. The when()
method makes it concise, and the block of code only executes when the condition is true.
2. Dynamic Validation Rules
Suppose you’re building a form where certain fields should only be validated if a specific condition is met. For example, the email field should only be required if the user selects the "newsletter" option.
Without when()
:
$rules = [
'email' => 'nullable',
];
if ($request->has('newsletter')) {
$rules['email'] = 'required|email';
}
$request->validate($rules);
With when()
:
$request->when($request->has('newsletter'), function () use ($request) {
$request->validate([
'email' => 'required|email',
]);
});
This is a cleaner and more readable way to apply conditional validation logic using when()
.
3. Conditional Data Merging for Specific Operations
In an e-commerce platform, you might want to apply a discount only if a specific coupon code is provided. Let's merge the discount data dynamically based on whether the coupon exists.
Without when()
:
$data = [
'total_price' => $cart->totalPrice(),
];
if ($request->has('coupon_code')) {
$coupon = Coupon::where('code', $request->input('coupon_code'))->first();
if ($coupon) {
$data['discount'] = $coupon->discount_amount;
}
}
return response()->json($data);
With when()
:
$data = [
'total_price' => $cart->totalPrice(),
];
$data = $data->when($request->has('coupon_code'), function ($data) use ($request) {
$coupon = Coupon::where('code', $request->input('coupon_code'))->first();
if ($coupon) {
$data['discount'] = $coupon->discount_amount;
}
return $data;
});
return response()->json($data);
Here, we apply a conditional discount based on the coupon code in a more streamlined and chainable way.
4. Simplifying Conditional Logic for User Status
Let’s say you have a system where you want to send a different message depending on whether a user is active or inactive.
Without unless()
:
if (!$user->isActive()) {
return "Your account is inactive. Please contact support.";
} else {
return "Welcome back!";
}
With unless()
:
return $user->unless($user->isActive(), function () {
return "Your account is inactive. Please contact support.";
})->otherwise(function () {
return "Welcome back!";
});
Using unless()
here helps condense the conditional logic into a single return statement.
5. Combining when()
and unless()
for Complex Flows
You can also combine when()
and unless()
for more complex conditional flows. For example, handling different user types (admin, guest, etc.) and showing them specific content.
$variable->when($user->isAdmin(), function ($variable) {
return $variable->adminDashboard();
})->unless($user->isAdmin(), function ($variable) {
return $variable->guestDashboard();
});
6. Payment Gateway Integration Based on User's Payment Method
Imagine you’re implementing a payment system where the payment method chosen by the user determines the flow of execution, such as whether to use a credit card, PayPal, or Bitcoin.
Without when()
:
if ($request->input('payment_method') == 'credit_card') {
// Handle credit card payment logic
} elseif ($request->input('payment_method') == 'paypal') {
// Handle PayPal payment logic
} elseif ($request->input('payment_method') == 'bitcoin') {
// Handle Bitcoin payment logic
}
With when()
:
$request->when($request->input('payment_method') == 'credit_card', function () {
// Handle credit card payment logic
})->when($request->input('payment_method') == 'paypal', function () {
// Handle PayPal payment logic
})->when($request->input('payment_method') == 'bitcoin', function () {
// Handle Bitcoin payment logic
});
This makes your payment handling more readable and simplifies the conditional logic for payment method selection.
7. Real Estate Property Price Calculation with Discounts
For a real estate application, if a user is a first-time buyer or using a special promo code, you might apply a discount to the property price.
Without when()
:
$price = $property->price;
if ($request->has('first_time_buyer')) {
$price -= 5000; // Discount for first-time buyers
}
if ($request->has('promo_code')) {
$promo = PromoCode::where('code', $request->input('promo_code'))->first();
if ($promo) {
$price -= $promo->discount;
}
}
return response()->json(['price' => $price]);
With when()
:
$price = $property->price;
$price = $price->when($request->has('first_time_buyer'), function ($price) {
return $price - 5000; // Discount for first-time buyers
});
$price = $price->when($request->has('promo_code'), function ($price) use ($request) {
$promo = PromoCode::where('code', $request->input('promo_code'))->first();
return $promo ? $price - $promo->discount : $price;
});
return response()->json(['price' => $price]);
This way, the code for calculating the price is cleaner and easier to maintain.
8. Medical Appointments with Insurance Verification
In a medical app, an appointment's payment might depend on whether the user has insurance, and you may need to verify it if provided.
Without when()
:
$payment = $appointment->cost;
if ($request->has('insurance_provider')) {
$insurance = Insurance::where('provider', $request->input('insurance_provider'))->first();
if ($insurance) {
$payment -= $insurance->coverage;
}
}
return response()->json(['payment' => $payment]);
With when()
:
$payment = $appointment->cost;
$payment = $payment->when($request->has('insurance_provider'), function ($payment) use ($request) {
$insurance = Insurance::where('provider', $request->input('insurance_provider'))->first();
return $insurance ? $payment - $insurance->coverage : $payment;
});
return response()->json(['payment' => $payment]);
This approach simplifies checking for insurance coverage and reduces clutter.
9. Bitcoin Price Adjustment Based on Market Conditions
Imagine you're building an app that allows users to buy Bitcoin, and the price fluctuates based on market conditions. If the market is volatile, you might want to add a fee to the price.
Without when()
:
$price = $bitcoin->currentPrice();
if ($market->isVolatile()) {
$price += 100; // Add a volatility fee
}
return response()->json(['price' => $price]);
With when()
:
$price = $bitcoin->currentPrice();
$price = $price->when($market->isVolatile(), function ($price) {
return $price + 100; // Add a volatility fee
});
return response()->json(['price' => $price]);
This simplifies the logic of applying a fee based on market volatility.
10. Conditional Product Availability in an E-commerce Store
Suppose you are building an e-commerce platform where products can only be shipped within certain regions. You want to check whether the product is available for a customer's location.
Without when()
:
$shippingFee = 0;
if ($customer->location == 'international') {
$shippingFee = $product->internationalShippingFee();
} else {
$shippingFee = $product->domesticShippingFee();
}
return response()->json(['shipping_fee' => $shippingFee]);
With when()
:
$shippingFee = $product->domesticShippingFee();
$shippingFee = $shippingFee->when($customer->location == 'international', function ($shippingFee) use ($product) {
return $product->internationalShippingFee();
});
return response()->json(['shipping_fee' => $shippingFee]);
The when()
method simplifies the conditional logic for determining shipping fees based on the customer's location.
11. Medical Treatment Plan Based on Patient's Health Conditions
Consider a healthcare application that assigns a treatment plan based on the patient's diagnosed health conditions. If the patient has a chronic condition, a long-term treatment plan might be suggested.
Without when()
:
$treatmentPlan = 'Standard Plan';
if ($patient->hasChronicCondition()) {
$treatmentPlan = 'Chronic Care Plan';
}
return response()->json(['treatment_plan' => $treatmentPlan]);
With when()
:
$treatmentPlan = 'Standard Plan';
$treatmentPlan = $treatmentPlan->when($patient->hasChronicCondition(), function ($treatmentPlan) {
return 'Chronic Care Plan';
});
return response()->json(['treatment_plan' => $treatmentPlan]);
This approach helps streamline the decision-making logic and makes it easier to handle more conditions in the future.
These examples demonstrate how the when()
and unless()
methods can be applied across various domains like payments, Bitcoin, real estate, and healthcare, making your Laravel code more readable, maintainable, and elegant. By embracing these methods, you can write cleaner code and enhance the maintainability of your Laravel applications.
Top comments (1)
Seeing the examples the when and unless methods don't blow me out of the water.
I don't understand what is wrong with the using if statements? Most of the examples could be ternary statements.
I also spotted an error in one of the examples.
I trained myself to write positive if statements, so the unless method is lost on me.
I don't see how the functions make code more readable, maintainable or elegant.
The methods make code even harder to read if you use the third parameter.
Thank you for the post! I will keep writing php.