Conditional Statements

Overview

Conditional statements allow your program to make decisions and execute different code paths based on specific conditions. PHP provides several types of conditional statements including if-else, switch, match (PHP 8+), and ternary operators.

If Statements

Basic If Statement

<?php
$age = 18;

if ($age >= 18) {
    echo "You are eligible to vote.";
}

// Single-line if (not recommended for readability)
if ($age >= 18) echo "Eligible to vote.";

// Boolean conditions
$isLoggedIn = true;
if ($isLoggedIn) {
    echo "Welcome back!";
}

// Checking variables
$username = "john";
if ($username) {  // Non-empty string is truthy
    echo "Hello, $username!";
}
?>

If-Else Statement

<?php
$temperature = 25;

if ($temperature > 30) {
    echo "It's hot outside!";
} else {
    echo "The weather is pleasant.";
}

// Multiple conditions
$score = 85;

if ($score >= 90) {
    echo "Grade: A";
} else if ($score >= 80) {
    echo "Grade: B";
} else if ($score >= 70) {
    echo "Grade: C";
} else if ($score >= 60) {
    echo "Grade: D";
} else {
    echo "Grade: F";
}

// Alternative syntax (useful in templates)
$user = getCurrentUser();
?>
<?php if ($user): ?>
    <p>Welcome, <?= $user->getName() ?>!</p>
<?php else: ?>
    <p>Please log in.</p>
<?php endif; ?>

Nested If Statements

<?php
$user = getCurrentUser();

if ($user) {
    if ($user->isActive()) {
        if ($user->hasPermission('admin')) {
            echo "Admin access granted.";
        } else {
            echo "Regular user access.";
        }
    } else {
        echo "Account is deactivated.";
    }
} else {
    echo "Please log in.";
}

// Better approach - early returns
function checkUserAccess($user) {
    if (!$user) {
        return "Please log in.";
    }
    
    if (!$user->isActive()) {
        return "Account is deactivated.";
    }
    
    if ($user->hasPermission('admin')) {
        return "Admin access granted.";
    }
    
    return "Regular user access.";
}
?>

Complex Conditions

Logical Operators in Conditions

<?php
$age = 25;
$hasLicense = true;
$hasInsurance = true;

// AND conditions
if ($age >= 18 && $hasLicense && $hasInsurance) {
    echo "You can legally drive.";
}

// OR conditions
$isWeekend = true;
$isHoliday = false;

if ($isWeekend || $isHoliday) {
    echo "No work today!";
}

// Mixed logical operators
$user = getCurrentUser();
$isAdmin = $user && $user->hasRole('admin');
$isModerator = $user && $user->hasRole('moderator');

if ($isAdmin || $isModerator) {
    echo "You have moderation privileges.";
}

// Using parentheses for clarity
if (($age >= 16 && $age < 18) && ($hasLicense || $hasPermit)) {
    echo "You can drive with restrictions.";
}
?>

Comparison Operators

<?php
$userInput = "5";
$expectedValue = 5;

// Loose comparison (type coercion)
if ($userInput == $expectedValue) {
    echo "Values match (loose comparison)";
}

// Strict comparison (no type coercion)
if ($userInput === $expectedValue) {
    echo "Values and types match";
} else {
    echo "Types don't match";
}

// null checking
$data = null;

if ($data === null) {
    echo "Data is null";
}

if (is_null($data)) {
    echo "Data is null (using function)";
}

// Empty value checking
$array = [];
$string = "";

if (empty($array)) {
    echo "Array is empty";
}

if (empty($string)) {
    echo "String is empty";
}

// isset checking
if (isset($_GET['page'])) {
    $page = $_GET['page'];
} else {
    $page = 1;
}

// Null coalescing operator (PHP 7+)
$page = $_GET['page'] ?? 1;
?>

Switch Statement

Basic Switch

<?php
$day = date('N'); // 1 (Monday) to 7 (Sunday)

switch ($day) {
    case 1:
        echo "Monday - Start of work week";
        break;
    case 2:
        echo "Tuesday - Getting into rhythm";
        break;
    case 3:
        echo "Wednesday - Middle of the week";
        break;
    case 4:
        echo "Thursday - Almost there";
        break;
    case 5:
        echo "Friday - Thank God it's Friday!";
        break;
    case 6:
    case 7:
        echo "Weekend - Time to relax";
        break;
    default:
        echo "Invalid day";
        break;
}
?>

Switch with Strings

<?php
$action = $_GET['action'] ?? 'home';

switch ($action) {
    case 'home':
        showHomePage();
        break;
    case 'about':
        showAboutPage();
        break;
    case 'contact':
        showContactPage();
        break;
    case 'login':
    case 'signin':
        showLoginPage();
        break;
    case 'logout':
    case 'signout':
        performLogout();
        break;
    default:
        show404Page();
        break;
}

// User roles with switch
$userRole = $user->getRole();

switch ($userRole) {
    case 'admin':
        $permissions = ['read', 'write', 'delete', 'manage_users'];
        break;
    case 'editor':
        $permissions = ['read', 'write', 'delete'];
        break;
    case 'author':
        $permissions = ['read', 'write'];
        break;
    case 'subscriber':
        $permissions = ['read'];
        break;
    default:
        $permissions = [];
        break;
}
?>

Switch Fall-through

<?php
$grade = 'B';

switch ($grade) {
    case 'A':
        echo "Excellent!";
        // Falls through to next case
    case 'B':
        echo "Well done!";
        // Falls through to next case
    case 'C':
        echo "You passed.";
        break;
    case 'D':
        echo "You barely passed.";
        break;
    case 'F':
        echo "You failed.";
        break;
    default:
        echo "Invalid grade.";
        break;
}

// Intentional fall-through for grouping
$month = date('n');

switch ($month) {
    case 12:
    case 1:
    case 2:
        $season = "Winter";
        break;
    case 3:
    case 4:
    case 5:
        $season = "Spring";
        break;
    case 6:
    case 7:
    case 8:
        $season = "Summer";
        break;
    case 9:
    case 10:
    case 11:
        $season = "Autumn";
        break;
    default:
        $season = "Unknown";
        break;
}
?>

Match Expression (PHP 8+)

Basic Match

<?php
$grade = 85;

$letter = match (true) {
    $grade >= 90 => 'A',
    $grade >= 80 => 'B',
    $grade >= 70 => 'C',
    $grade >= 60 => 'D',
    default => 'F'
};

echo $letter; // "B"

// Exact value matching
$day = 'Monday';

$mood = match ($day) {
    'Monday' => 'Tired',
    'Tuesday', 'Wednesday', 'Thursday' => 'Working',
    'Friday' => 'Excited',
    'Saturday', 'Sunday' => 'Relaxed',
    default => 'Unknown'
};

echo $mood; // "Tired"
?>

Match vs Switch Differences

<?php
// Match is an expression (returns value)
$result = match ($value) {
    1 => 'one',
    2 => 'two',
    default => 'other'
};

// Switch is a statement (doesn't return value)
switch ($value) {
    case 1:
        $result = 'one';
        break;
    case 2:
        $result = 'two';
        break;
    default:
        $result = 'other';
        break;
}

// Match uses strict comparison (===)
$input = '1';

$switchResult = match ($input) {
    1 => 'number one',      // Won't match (strict comparison)
    '1' => 'string one',    // Will match
    default => 'other'
};

// Match doesn't fall through
$value = 1;

$matchResult = match ($value) {
    1 => 'one',
    1 => 'uno',  // This causes error (duplicate case)
};

// Match can have complex expressions
$user = getCurrentUser();

$access = match (true) {
    $user === null => 'guest',
    $user->isAdmin() => 'admin',
    $user->isModerator() => 'moderator',
    $user->isActive() => 'user',
    default => 'inactive'
};
?>

Ternary Operator

Basic Ternary Operator

<?php
$age = 20;

// Basic ternary operator
$status = ($age >= 18) ? 'adult' : 'minor';
echo $status; // "adult"

// Using function calls
$user = getCurrentUser();
$username = $user ? $user->getName() : 'Guest';

// Ternary in string interpolation
$items = 5;
echo "You have $items " . ($items === 1 ? 'item' : 'items');

// Ternary for default values
$page = $_GET['page'] ?? null;
$currentPage = $page ? (int)$page : 1;
?>

Nested Ternary Operators (Use Carefully)

<?php
$score = 85;

// Nested ternary (hard to read)
$grade = ($score >= 90) ? 'A' : 
         (($score >= 80) ? 'B' : 
         (($score >= 70) ? 'C' : 
         (($score >= 60) ? 'D' : 'F')));

// Better approach
function getGrade($score) {
    if ($score >= 90) return 'A';
    if ($score >= 80) return 'B';
    if ($score >= 70) return 'C';
    if ($score >= 60) return 'D';
    return 'F';
}

$grade = getGrade($score);
?>

Elvis Operator (PHP 5.3+)

<?php
// Elvis operator ?: (shortened ternary)
$username = $user->getName() ?: 'Anonymous';

// Equivalent to:
$username = $user->getName() ? $user->getName() : 'Anonymous';

// For default values
$config = [
    'theme' => 'dark',
    'language' => 'en'
];

$theme = $config['theme'] ?: 'light';
$language = $config['language'] ?: 'en';
$timezone = $config['timezone'] ?: 'UTC';

// Beware of falsy values
$count = 0;
$display = $count ?: 'No items'; // "No items" (0 is falsy)

// Use null coalescing for null checks
$display = $count ?? 'No items'; // "0" (only null triggers default)
?>

Practical Examples

User Authentication

<?php
function authenticateUser($username, $password) {
    if (empty($username) || empty($password)) {
        return ['success' => false, 'message' => 'Username and password required'];
    }
    
    $user = findUserByUsername($username);
    
    if (!$user) {
        return ['success' => false, 'message' => 'User not found'];
    }
    
    if (!$user->isActive()) {
        return ['success' => false, 'message' => 'Account is inactive'];
    }
    
    if (!password_verify($password, $user->getPasswordHash())) {
        return ['success' => false, 'message' => 'Invalid password'];
    }
    
    return ['success' => true, 'user' => $user];
}

// Usage
$result = authenticateUser($_POST['username'] ?? '', $_POST['password'] ?? '');

if ($result['success']) {
    $_SESSION['user_id'] = $result['user']->getId();
    header('Location: /dashboard');
} else {
    $error = $result['message'];
}
?>

Form Validation

<?php
function validateContactForm($data) {
    $errors = [];
    
    // Name validation
    if (empty($data['name'])) {
        $errors['name'] = 'Name is required';
    } elseif (strlen($data['name']) < 2) {
        $errors['name'] = 'Name must be at least 2 characters';
    }
    
    // Email validation
    if (empty($data['email'])) {
        $errors['email'] = 'Email is required';
    } elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'Invalid email format';
    }
    
    // Message validation
    if (empty($data['message'])) {
        $errors['message'] = 'Message is required';
    } elseif (strlen($data['message']) < 10) {
        $errors['message'] = 'Message must be at least 10 characters';
    }
    
    // Age validation (optional)
    if (!empty($data['age'])) {
        if (!is_numeric($data['age'])) {
            $errors['age'] = 'Age must be a number';
        } elseif ($data['age'] < 13) {
            $errors['age'] = 'Must be at least 13 years old';
        } elseif ($data['age'] > 120) {
            $errors['age'] = 'Invalid age';
        }
    }
    
    return $errors;
}

// Usage
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $errors = validateContactForm($_POST);
    
    if (empty($errors)) {
        // Process form
        sendContactEmail($_POST);
        $success = "Message sent successfully!";
    }
}
?>

Permission System

<?php
class PermissionChecker {
    private $user;
    
    public function __construct($user) {
        $this->user = $user;
    }
    
    public function canViewPage($page) {
        if (!$this->user) {
            return $page === 'home' || $page === 'login';
        }
        
        switch ($page) {
            case 'admin':
                return $this->user->hasRole('admin');
            case 'moderator':
                return $this->user->hasRole('admin') || $this->user->hasRole('moderator');
            case 'profile':
            case 'settings':
                return $this->user->isActive();
            case 'home':
            case 'about':
            case 'contact':
                return true;
            default:
                return false;
        }
    }
    
    public function canEditContent($content) {
        if (!$this->user || !$this->user->isActive()) {
            return false;
        }
        
        // Admin can edit everything
        if ($this->user->hasRole('admin')) {
            return true;
        }
        
        // Users can edit their own content
        if ($content->getAuthorId() === $this->user->getId()) {
            return true;
        }
        
        // Moderators can edit published content
        if ($this->user->hasRole('moderator') && $content->isPublished()) {
            return true;
        }
        
        return false;
    }
}

// Usage
$checker = new PermissionChecker($currentUser);

if ($checker->canViewPage('admin')) {
    showAdminPanel();
} else {
    showAccessDenied();
}
?>

API Response Handler

<?php
function handleApiResponse($response) {
    $statusCode = $response->getStatusCode();
    
    switch (true) {
        case ($statusCode >= 200 && $statusCode < 300):
            return [
                'success' => true,
                'data' => $response->getData(),
                'message' => 'Request successful'
            ];
            
        case ($statusCode === 400):
            return [
                'success' => false,
                'error' => 'Bad request',
                'message' => 'Please check your request parameters'
            ];
            
        case ($statusCode === 401):
            return [
                'success' => false,
                'error' => 'Unauthorized',
                'message' => 'Please log in to continue'
            ];
            
        case ($statusCode === 403):
            return [
                'success' => false,
                'error' => 'Forbidden',
                'message' => 'You do not have permission to access this resource'
            ];
            
        case ($statusCode === 404):
            return [
                'success' => false,
                'error' => 'Not found',
                'message' => 'The requested resource was not found'
            ];
            
        case ($statusCode >= 500):
            return [
                'success' => false,
                'error' => 'Server error',
                'message' => 'An internal server error occurred'
            ];
            
        default:
            return [
                'success' => false,
                'error' => 'Unknown error',
                'message' => "Unexpected status code: $statusCode"
            ];
    }
}
?>

Best Practices

Readability and Maintainability

<?php
// Good: Clear and readable
if ($user && $user->isActive() && $user->hasPermission('edit')) {
    allowEditing();
}

// Bad: Too complex in one line
if ($user && $user->isActive() && ($user->hasRole('admin') || ($user->hasRole('editor') && $user->getExperience() > 6)) && !$user->isSuspended()) {
    // Hard to understand
}

// Better: Break down complex conditions
$isActiveUser = $user && $user->isActive() && !$user->isSuspended();
$hasEditPermission = $user && ($user->hasRole('admin') || 
                              ($user->hasRole('editor') && $user->getExperience() > 6));

if ($isActiveUser && $hasEditPermission) {
    allowEditing();
}

// Use early returns to reduce nesting
function processOrder($order) {
    if (!$order) {
        return false;
    }
    
    if (!$order->isValid()) {
        return false;
    }
    
    if ($order->getTotal() <= 0) {
        return false;
    }
    
    // Process the order
    return true;
}
?>

Next Steps

Now that you understand conditional statements, let's explore loops in Loops.

Practice Exercises

  1. Create a grade calculator using if-elseif statements
  2. Build a simple router using switch statements
  3. Implement user role checking with match expressions
  4. Create a form validator with comprehensive error checking
  5. Build a permission system using nested conditions

Mastering conditional statements is essential for creating dynamic and responsive PHP applications!