Understanding PHP Conditionals: If-Elseif-Else Statements
Learning Objectives
- Master PHP programming concepts
- Write clean, maintainable code
- Apply best practices
- Build dynamic applications
Introduction to If-Elseif-Else Statements
Welcome to our continuing journey through PHP conditional statements! In our previous sessions, we explored basic if statements and if-else statements. Today, we're taking the next step with if-elseif-else statements, which allow us to check multiple conditions in sequence and execute different code blocks based on which condition is met first.
The Traffic Intersection Analogy
Think of an if-elseif-else statement as a traffic intersection with multiple possible routes. When your program reaches this intersection, it evaluates each condition in sequence, taking the first path where the condition is true. If none of the specified conditions are true, it takes the default "else" path.
Basic If-Elseif-Else Syntax
The if-elseif-else statement expands on the if-else statement by adding one or more conditions to check between the initial "if" and the final "else".
Basic Syntax
if (first_condition) {
// Code to execute if first_condition is true
} elseif (second_condition) {
// Code to execute if first_condition is false but second_condition is true
} elseif (third_condition) {
// Code to execute if both first and second conditions are false but third_condition is true
} else {
// Code to execute if all conditions are false
}
Let's break down the components:
- if: The keyword that starts the conditional statement
- elseif: The keyword that introduces additional conditions to check
- else: The keyword that introduces the default code block (optional)
- condition: Each expression that evaluates to either true or false
- { }: Curly braces enclosing each code block to execute when its corresponding condition is true
Note on Syntax Variations
PHP allows elseif to be written as two words: else if. Both formats work identically, but it's good practice to be consistent with whichever style you choose:
// These are functionally identical
if ($condition1) {
// Code...
} elseif ($condition2) {
// Code...
} else {
// Code...
}
if ($condition1) {
// Code...
} else if ($condition2) {
// Code...
} else {
// Code...
}
Real-World Example: Grading System
A classic example of if-elseif-else statements is a grading system:
$score = 85;
if ($score >= 90) {
echo "Grade: A";
} elseif ($score >= 80) {
echo "Grade: B";
} elseif ($score >= 70) {
echo "Grade: C";
} elseif ($score >= 60) {
echo "Grade: D";
} else {
echo "Grade: F";
}
With a score of 85, this code will output "Grade: B". The program checks each condition in order and executes the code block for the first condition that evaluates to true.
How If-Elseif-Else Evaluation Flows
Key Concepts to Understand
Sequential Evaluation
Conditions are evaluated in order, from top to bottom. Once a condition evaluates to true, its corresponding code block executes, and all subsequent conditions are skipped.
Short-Circuit Behavior
PHP stops checking conditions as soon as it finds one that's true. This is called "short-circuit" behavior and is important for both performance and logic flow.
Optional Else Block
The final "else" block is optional. If omitted and none of the conditions evaluate to true, no code will execute.
Unlimited Elseif Blocks
You can have as many "elseif" blocks as needed, though too many may indicate that a switch statement or other approach might be more appropriate.
Visual Flow of Execution
In this example, with $score = 85, the code checks the first condition ($score >= 90), which is false. It then checks the second condition ($score >= 80), which is true, so it executes the corresponding code block and skips all remaining conditions.
Practical Examples of If-Elseif-Else Statements
User Role Permissions
Displaying different UI elements based on user role:
$userRole = "editor";
if ($userRole === "admin") {
echo "Welcome, Administrator. You have full control of the system.";
echo "<button>Access Admin Panel</button>";
} elseif ($userRole === "editor") {
echo "Welcome, Editor. You can create and modify content.";
echo "<button>Create New Post</button>";
} elseif ($userRole === "author") {
echo "Welcome, Author. You can create your own content.";
echo "<button>My Posts</button>";
} else {
echo "Welcome, Visitor. You can browse our content.";
echo "<button>Subscribe</button>";
}
Shipping Cost Calculator
Determining shipping costs based on order weight:
$orderWeight = 3.5; // Weight in kg
$shippingCost = 0;
if ($orderWeight <= 0.5) {
$shippingCost = 5;
} elseif ($orderWeight <= 2) {
$shippingCost = 10;
} elseif ($orderWeight <= 5) {
$shippingCost = 15;
} elseif ($orderWeight <= 10) {
$shippingCost = 20;
} else {
$shippingCost = 25;
}
echo "Shipping cost: $" . $shippingCost;
HTTP Response Handling
Handling different HTTP response codes:
$httpStatusCode = 404;
$message = "";
if ($httpStatusCode === 200) {
$message = "Success! The request was completed successfully.";
} elseif ($httpStatusCode === 301 || $httpStatusCode === 302) {
$message = "Redirecting to new location...";
} elseif ($httpStatusCode === 404) {
$message = "Error: The requested resource was not found.";
} elseif ($httpStatusCode === 500) {
$message = "Error: Internal server error. Please try again later.";
} else {
$message = "An unexpected response was received. Status code: " . $httpStatusCode;
}
echo $message;
WordPress-Specific Example: Content Template Selection
In WordPress theme development, you often need to choose different templates based on the post type:
// WordPress function to get current post type
$postType = get_post_type();
if ($postType === 'post') {
// Load the standard blog post template
include(get_template_directory() . '/template-parts/content-post.php');
} elseif ($postType === 'page') {
// Load the page template
include(get_template_directory() . '/template-parts/content-page.php');
} elseif ($postType === 'product') {
// Load the product template for WooCommerce
include(get_template_directory() . '/template-parts/content-product.php');
} elseif ($postType === 'portfolio') {
// Load the portfolio item template
include(get_template_directory() . '/template-parts/content-portfolio.php');
} else {
// Load a generic fallback template
include(get_template_directory() . '/template-parts/content.php');
}
Why Order Matters in If-Elseif-Else
One of the most critical aspects of if-elseif-else statements is the order of conditions. Since PHP evaluates conditions sequentially and executes the code block for the first condition that evaluates to true, the order can dramatically affect your program's behavior.
Example: Incorrectly Ordered Conditions
$score = 95;
// INCORRECT ORDER
if ($score >= 60) {
echo "You passed!"; // This will execute for ANY score >= 60
} elseif ($score >= 90) {
echo "Excellent job!"; // This will NEVER execute!
} else {
echo "You failed.";
}
In this example, a score of 95 would only trigger the first condition ("You passed!"), even though we intended to display "Excellent job!" for scores above 90. The second condition is never reached because any score that meets the second condition also meets the first one.
Example: Correctly Ordered Conditions
$score = 95;
// CORRECT ORDER - Most specific to least specific
if ($score >= 90) {
echo "Excellent job!"; // This will execute for scores >= 90
} elseif ($score >= 60) {
echo "You passed!"; // This will execute for scores 60-89
} else {
echo "You failed."; // This will execute for scores < 60
}
By ordering conditions from most specific to least specific (or in this case, from highest threshold to lowest), we ensure that each condition serves its intended purpose.
Best Practice: Arrange Conditions Thoughtfully
When writing if-elseif-else statements:
- Arrange conditions from most specific to least specific
- For range checks, start with the highest/narrowest range
- Consider which conditions are subsets of others
- Use mutually exclusive conditions when possible
Alternative Syntax for Templates
As with if and if-else statements, PHP offers an alternative syntax for if-elseif-else statements that's particularly useful in template files:
<!-- Standard syntax -->
<?php
if ($userRole === "admin") {
echo "<div class='admin-dashboard'>Admin content</div>";
} elseif ($userRole === "editor") {
echo "<div class='editor-dashboard'>Editor content</div>";
} else {
echo "<div class='user-dashboard'>User content</div>";
}
?>
<!-- Alternative syntax -->
<?php if ($userRole === "admin"): ?>
<div class='admin-dashboard'>
Admin content
</div>
<?php elseif ($userRole === "editor"): ?>
<div class='editor-dashboard'>
Editor content
</div>
<?php else: ?>
<div class='user-dashboard'>
User content
</div>
<?php endif; ?>
WordPress Theme Example: Post Format Handling
This syntax is commonly used in WordPress themes for handling different post formats:
<?php
// WordPress function to check post format
$format = get_post_format();
?>
<article id="post-<?php the_ID(); ?>" class="<?php echo $format ? 'format-' . $format : 'format-standard'; ?>">
<?php if ($format === 'video'): ?>
<div class="video-container">
<?php echo get_post_meta(get_the_ID(), 'video_embed', true); ?>
</div>
<?php elseif ($format === 'gallery'): ?>
<div class="gallery-slider">
<?php echo get_post_gallery(); ?>
</div>
<?php elseif ($format === 'audio'): ?>
<div class="audio-player">
<?php echo get_post_meta(get_the_ID(), 'audio_embed', true); ?>
</div>
<?php else: ?>
<?php if (has_post_thumbnail()): ?>
<div class="featured-image">
<?php the_post_thumbnail('large'); ?>
</div>
<?php endif; ?>
<?php endif; ?>
<div class="entry-content">
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</div>
</article>
Common If-Elseif-Else Patterns
Value Range Checks
Checking if a value falls within different ranges:
$temperature = 32;
if ($temperature >= 30) {
echo "Hot weather! Stay hydrated.";
} elseif ($temperature >= 20) {
echo "Pleasant temperature.";
} elseif ($temperature >= 10) {
echo "Cool weather. Consider a light jacket.";
} elseif ($temperature >= 0) {
echo "Cold weather. Wear warm clothes.";
} else {
echo "Freezing temperatures! Bundle up well.";
}
Type-Based Processing
Handling different data types with specific logic:
function processValue($value) {
if (is_numeric($value)) {
return $value * 2; // Double numeric values
} elseif (is_string($value)) {
return strtoupper($value); // Uppercase string values
} elseif (is_bool($value)) {
return !$value; // Invert boolean values
} elseif (is_array($value)) {
return count($value); // Return array count
} else {
return null; // Handle other types
}
}
echo processValue(5); // Outputs: 10
echo processValue("hello"); // Outputs: HELLO
var_dump(processValue(true)); // Outputs: bool(false)
echo processValue([1, 2, 3]); // Outputs: 3
Error Handling and Validation
Validating input with specific error messages:
function validateUsername($username) {
if (empty($username)) {
return "Username is required.";
} elseif (strlen($username) < 5) {
return "Username must be at least 5 characters long.";
} elseif (strlen($username) > 20) {
return "Username cannot be longer than 20 characters.";
} elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
return "Username can only contain letters, numbers, and underscores.";
} else {
return true; // Username is valid
}
}
$result = validateUsername("user@name");
if ($result !== true) {
echo $result; // Outputs: Username can only contain letters, numbers, and underscores.
}
State Machine Transitions
Implementing simple state machines:
$currentState = "pending";
$action = "approve";
if ($currentState === "pending" && $action === "approve") {
$newState = "approved";
} elseif ($currentState === "pending" && $action === "reject") {
$newState = "rejected";
} elseif ($currentState === "approved" && $action === "revoke") {
$newState = "pending";
} elseif ($currentState === "rejected" && $action === "reconsider") {
$newState = "pending";
} else {
$newState = $currentState; // Invalid state transition, keep current state
}
echo "Transitioned from $currentState to $newState";
Refactoring Complex If-Elseif Statements
While if-elseif-else statements are powerful, they can become unwieldy when you have many conditions or complex logic. Here are some approaches for refactoring complex conditional chains:
Approach 1: Use Switch Statements
When comparing a single variable against multiple values, a switch statement can be clearer:
// If-elseif approach
$dayOfWeek = date('l');
if ($dayOfWeek === 'Monday') {
echo "Start of the work week";
} elseif ($dayOfWeek === 'Tuesday') {
echo "Second day of work";
} elseif ($dayOfWeek === 'Wednesday') {
echo "Midweek";
} elseif ($dayOfWeek === 'Thursday') {
echo "Almost there";
} elseif ($dayOfWeek === 'Friday') {
echo "Last workday";
} elseif ($dayOfWeek === 'Saturday' || $dayOfWeek === 'Sunday') {
echo "Weekend!";
}
// Switch approach - cleaner for simple equality checks
switch ($dayOfWeek) {
case 'Monday':
echo "Start of the work week";
break;
case 'Tuesday':
echo "Second day of work";
break;
case 'Wednesday':
echo "Midweek";
break;
case 'Thursday':
echo "Almost there";
break;
case 'Friday':
echo "Last workday";
break;
case 'Saturday':
case 'Sunday':
echo "Weekend!";
break;
}
We'll explore switch statements in detail in our next session.
Approach 2: Lookup Tables/Arrays
For simple mappings, an array can replace conditionals:
// If-elseif approach
function getMonthName($monthNum) {
if ($monthNum === 1) {
return "January";
} elseif ($monthNum === 2) {
return "February";
} elseif ($monthNum === 3) {
return "March";
}
// ... and so on for all 12 months
}
// Array lookup approach - much cleaner
function getMonthNameArray($monthNum) {
$months = [
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December"
];
return $months[$monthNum] ?? "Invalid month";
}
echo getMonthNameArray(3); // Outputs: March
Approach 3: Early Returns in Functions
For validation and error checking, early returns can simplify logic:
// If-elseif approach
function processUserData($userData) {
if (empty($userData)) {
return "Error: No data provided";
} elseif (!isset($userData['email'])) {
return "Error: Email is required";
} elseif (!filter_var($userData['email'], FILTER_VALIDATE_EMAIL)) {
return "Error: Valid email is required";
} elseif (!isset($userData['name']) || strlen($userData['name']) < 2) {
return "Error: Name must be at least 2 characters";
} else {
// Process the data
return "Data processed successfully";
}
}
// Early returns approach - cleaner and avoids deep nesting
function processUserDataWithEarlyReturns($userData) {
if (empty($userData)) {
return "Error: No data provided";
}
if (!isset($userData['email'])) {
return "Error: Email is required";
}
if (!filter_var($userData['email'], FILTER_VALIDATE_EMAIL)) {
return "Error: Valid email is required";
}
if (!isset($userData['name']) || strlen($userData['name']) < 2) {
return "Error: Name must be at least 2 characters";
}
// Process the data
return "Data processed successfully";
}
Best Practices for If-Elseif-Else Statements
Keep Conditions Simple and Readable
Complex conditions can be difficult to understand and maintain. Break them down into variables with descriptive names:
// Hard to read at a glance
if (($age >= 18 && $hasId) || ($age >= 16 && $hasParentalConsent && $hasSchoolId)) {
// Allow access
}
// More readable
$isAdult = $age >= 18 && $hasId;
$isAuthorizedMinor = $age >= 16 && $hasParentalConsent && $hasSchoolId;
if ($isAdult || $isAuthorizedMinor) {
// Allow access
}
Use Consistent Formatting
Consistent indentation and brace placement make code more readable:
// Consistent formatting
if ($condition1) {
// Code block
} elseif ($condition2) {
// Code block
} else {
// Code block
}
Consider the Default Case Carefully
Make sure your default (else) case handles unexpected inputs gracefully:
function getColorName($colorCode) {
if ($colorCode === 1) {
return "Red";
} elseif ($colorCode === 2) {
return "Green";
} elseif ($colorCode === 3) {
return "Blue";
} else {
// Handle unexpected input gracefully
return "Unknown color (Code: " . htmlspecialchars($colorCode) . ")";
}
}
Avoid Deep Nesting
Deeply nested if-elseif-else statements can be hard to follow. Consider refactoring when nesting goes beyond 2-3 levels:
// Deeply nested - hard to follow
if ($userLoggedIn) {
if ($userHasPermission) {
if ($contentExists) {
if (!$contentIsLocked) {
// Display content
} else {
// Content is locked
}
} else {
// Content doesn't exist
}
} else {
// No permission
}
} else {
// Not logged in
}
// Refactored with early returns and guard clauses
if (!$userLoggedIn) {
return "Please log in to view this content.";
}
if (!$userHasPermission) {
return "You don't have permission to access this content.";
}
if (!$contentExists) {
return "The requested content does not exist.";
}
if ($contentIsLocked) {
return "This content is currently locked.";
}
// Display content
Consider Alternatives for Complex Cases
If your if-elseif chain is getting very long (more than 5-7 conditions), consider alternatives like switch statements, lookup arrays, or more advanced patterns.
Common Pitfalls and How to Avoid Them
Overlapping Conditions
When conditions overlap, some code blocks might never execute:
$score = 95;
// INCORRECT - overlapping conditions
if ($score >= 60) {
echo "You passed.";
} elseif ($score >= 90) { // This will never execute!
echo "Excellent job!";
}
// CORRECT - non-overlapping conditions
if ($score >= 90) {
echo "Excellent job!";
} elseif ($score >= 60) {
echo "You passed.";
}
Missing Breaks in Switch (Preview)
When we cover switch statements next session, we'll see how missing break statements can cause unexpected "fall-through" behavior:
$dayType = '';
$day = 'Saturday';
switch ($day) {
case 'Monday':
case 'Tuesday':
case 'Wednesday':
case 'Thursday':
case 'Friday':
$dayType = 'Weekday';
break; // Without this break, execution would "fall through" to the next case
case 'Saturday':
case 'Sunday':
$dayType = 'Weekend';
}
echo "$day is a $dayType.";
Assignment vs. Comparison
Using assignment (=) instead of comparison (== or ===) in conditions:
$status = "pending";
// INCORRECT - uses assignment, not comparison
if ($status = "approved") { // This assigns "approved" to $status and then evaluates to true
echo "The transaction is approved.";
} elseif ($status = "pending") { // This will never be reached!
echo "The transaction is pending.";
}
// CORRECT - uses comparison
if ($status === "approved") {
echo "The transaction is approved.";
} elseif ($status === "pending") {
echo "The transaction is pending.";
}
Forgetting the Last Else
Omitting the final else can leave edge cases unhandled:
function getLetterGrade($score) {
if ($score >= 90) {
return 'A';
} elseif ($score >= 80) {
return 'B';
} elseif ($score >= 70) {
return 'C';
} elseif ($score >= 60) {
return 'D';
}
// Missing the else case!
// What happens if $score < 60?
}
// BETTER - handle all possible cases
function getLetterGradeComplete($score) {
if ($score >= 90) {
return 'A';
} elseif ($score >= 80) {
return 'B';
} elseif ($score >= 70) {
return 'C';
} elseif ($score >= 60) {
return 'D';
} else {
return 'F';
}
}
Looking Ahead: Switch Statements and Ternary Operators
Now that we've mastered if-elseif-else statements, our next topic will be switch statements, which provide an alternative syntax for comparing a single variable against multiple values. After that, we'll explore the ternary operator, a compact way to write simple if-else expressions.
Preview: Switch Statement
$dayOfWeek = date('l');
switch ($dayOfWeek) {
case 'Monday':
echo "Start of the week";
break;
case 'Wednesday':
echo "Midweek";
break;
case 'Friday':
echo "Almost weekend";
break;
case 'Saturday':
case 'Sunday':
echo "Weekend!";
break;
default:
echo "Regular day";
}
Preview: Ternary Operator
$age = 20;
// Instead of:
if ($age >= 18) {
$status = "adult";
} else {
$status = "minor";
}
// You can write:
$status = ($age >= 18) ? "adult" : "minor";
echo "This person is an $status.";
Practice Exercises
Exercise 1: Ticket Pricing
Write a PHP script for a movie theater that calculates ticket prices based on age. Children (under 13) pay $8, teens (13-17) pay $10, adults (18-59) pay $12, and seniors (60+) pay $9.
Reveal Solution
$age = 25;
$ticketPrice = 0;
if ($age < 13) {
$ticketPrice = 8;
} elseif ($age <= 17) {
$ticketPrice = 10;
} elseif ($age <= 59) {
$ticketPrice = 12;
} else {
$ticketPrice = 9;
}
echo "Ticket price: $$ticketPrice";
Exercise 2: Payment Method Handling
Write a PHP snippet for an e-commerce site that displays different messages based on the payment method selected. Handle credit card, PayPal, bank transfer, and a default message for other methods.
Reveal Solution
$paymentMethod = "bank_transfer";
$message = "";
if ($paymentMethod === "credit_card") {
$message = "You'll be redirected to our secure payment processor to complete your credit card payment.";
} elseif ($paymentMethod === "paypal") {
$message = "You'll be redirected to PayPal to complete your purchase.";
} elseif ($paymentMethod === "bank_transfer") {
$message = "Please use the following details to make your bank transfer. Your order will be processed after payment is received.";
} else {
$message = "Please follow the instructions for your selected payment method.";
}
echo $message;
Exercise 3: WordPress Content Conditional
Write a PHP snippet for a WordPress theme that displays different messages based on post status. Handle 'publish', 'draft', 'pending', and 'private' statuses with appropriate messages.
Reveal Solution
<?php
// WordPress function to get post status
$postStatus = get_post_status();
$statusMessage = "";
if ($postStatus === 'publish') {
$statusMessage = "This post is published and visible to the public.";
} elseif ($postStatus === 'draft') {
$statusMessage = "This post is a draft and is not yet published.";
} elseif ($postStatus === 'pending') {
$statusMessage = "This post is pending review before publication.";
} elseif ($postStatus === 'private') {
$statusMessage = "This post is private and only visible to site administrators.";
} else {
$statusMessage = "This post has a custom status: " . $postStatus;
}
?>
<div class="status-indicator">
<?php echo $statusMessage; ?>
</div>
Exercise 4: Shipping Method Selection
Create a PHP script that determines shipping method and cost based on package weight and destination. If the package is being shipped domestically, use standard shipping for packages under 5 kg ($5.99), express shipping for packages 5-10 kg ($9.99), and premium shipping for packages over 10 kg ($12.99). For international shipping, the rates are $15.99, $19.99, and $24.99 respectively.
Reveal Solution
$weight = 7.5; // Package weight in kg
$isInternational = true;
$shippingMethod = "";
$shippingCost = 0;
if ($isInternational) {
if ($weight < 5) {
$shippingMethod = "Standard International";
$shippingCost = 15.99;
} elseif ($weight <= 10) {
$shippingMethod = "Express International";
$shippingCost = 19.99;
} else {
$shippingMethod = "Premium International";
$shippingCost = 24.99;
}
} else {
if ($weight < 5) {
$shippingMethod = "Standard Domestic";
$shippingCost = 5.99;
} elseif ($weight <= 10) {
$shippingMethod = "Express Domestic";
$shippingCost = 9.99;
} else {
$shippingMethod = "Premium Domestic";
$shippingCost = 12.99;
}
}
echo "Recommended Shipping: $shippingMethod
";
echo "Shipping Cost: $$shippingCost";
Additional Resources
Homework Assignment
Continuing to build on our grading system, enhance it with the following requirements:
- Create variables for
$studentName,$score(between 0 and 100), and$attendancePercentage(between 0 and 100) - Using if-elseif-else statements, determine the letter grade based on the score, but with a twist:
- If attendance is below 75%, apply a one-grade penalty (e.g., B becomes C)
- If attendance is above 95%, add a "+" to the grade (unless it's an A, which becomes A+)
- Calculate and display a comprehensive student report that includes:
- Student name
- Original score
- Attendance percentage
- Final letter grade (after any attendance adjustments)
- A performance assessment message based on both their score and attendance
- Use if-elseif-else statements to determine a personalized message based on different combinations of grades and attendance
- Bonus: Add validation for input values and handle edge cases
Submit your code and a brief explanation of your solution, including how you structured your if-elseif-else statements for maximum readability and correctness.