条件语句

概述

条件语句是编程中最基础也是最重要的控制结构之一。它允许程序根据不同的条件执行不同的代码块,让程序具有"决策"能力。在PHP中,主要有以下几种条件语句:

  • if 语句 - 单一条件判断
  • if-else 语句 - 二选一判断
  • if-elseif-else 语句 - 多重条件判断
  • switch 语句 - 多值匹配判断

if 语句

基本语法

if (条件表达式) {
    // 当条件为 true 时执行的代码块
}

语法说明

  • 条件表达式:必须是布尔值或可以转换为布尔值的表达式
  • 代码块:用花括号 {} 包围的代码,即使只有一行语句也建议使用花括号
  • 执行流程:如果条件表达式的值为 true,则执行代码块;否则跳过

基础示例

<?php
// 简单的条件判断
$age = 18;

if ($age >= 18) {
    echo "您已经成年了!<br>";  // 输出:您已经成年了!
}

// 使用变量的条件判断
$hasLogin = true;
if ($hasLogin) {
    echo "欢迎回来!<br>";  // 输出:欢迎回来!
}

// 复杂条件表达式
$score = 85;
if ($score >= 60 && $score <= 100) {
    echo "恭喜您,考试通过了!<br>";  // 输出:恭喜您,考试通过了!
}
?>

if-else 语句

基本语法

if (条件表达式) {
    // 当条件为 true 时执行的代码块
} else {
    // 当条件为 false 时执行的代码块
}

语法说明

  • else 部分是可选的,当 if 条件不满足时执行
  • 只有一个 else 块,且必须紧跟在 if 块后面

实际应用示例

<?php
// 用户登录验证示例
$username = "admin";
$password = "123456";

if ($username === "admin" && $password === "123456") {
    echo "登录成功!欢迎管理员。<br>";
} else {
    echo "用户名或密码错误!<br>";
}

// 成绩判断示例
$score = 75;

if ($score >= 60) {
    echo "恭喜及格!<br>";
    echo "您的成绩是:" . $score . "分<br>";
} else {
    echo "很遗憾,您没有通过考试。<br>";
    echo "需要补考,请努力学习!<br>";
}

// 文件存在检查示例
$filename = "config.php";

if (file_exists($filename)) {
    echo "配置文件存在,正在读取配置...<br>";
    // 这里可以包含配置文件
} else {
    echo "配置文件不存在,使用默认配置。<br>";
}
?>

if-elseif-else 语句

基本语法

if (条件1) {
    // 条件1为 true 时执行
} elseif (条件2) {
    // 条件1为 false 且 条件2为 true 时执行
} elseif (条件3) {
    // 条件1、条件2都为 false 且 条件3为 true 时执行
} else {
    // 所有条件都为 false 时执行
}

语法说明

  • 可以有多个 elseif
  • 条件按顺序判断,一旦找到 true 的条件就执行对应代码块,然后跳出整个结构
  • else 块是可选的,但通常建议包含以处理所有未预料的情况

实际应用示例

<?php
// 学生成绩等级评定
$score = 85;

if ($score >= 90) {
    $grade = 'A';
    $comment = '优秀!';
} elseif ($score >= 80) {
    $grade = 'B';
    $comment = '良好!';
} elseif ($score >= 70) {
    $grade = 'C';
    $comment = '中等';
} elseif ($score >= 60) {
    $grade = 'D';
    $comment = '及格';
} else {
    $grade = 'F';
    $comment = '不及格';
}

echo "成绩:$score 分<br>";
echo "等级:$grade<br>";
echo "评价:$comment<br>";

// 用户权限检查示例
$userRole = 'editor';

if ($userRole === 'admin') {
    $permissions = ['read', 'write', 'delete', 'manage_users'];
    echo "管理员权限:可以执行所有操作<br>";
} elseif ($userRole === 'editor') {
    $permissions = ['read', 'write'];
    echo "编辑权限:可以读取和编辑内容<br>";
} elseif ($userRole === 'viewer') {
    $permissions = ['read'];
    echo "查看者权限:只能读取内容<br>";
} else {
    $permissions = [];
    echo "未知角色,没有权限<br>";
}

// 表单验证示例
$name = "张三";
$email = "zhangsan@example.com";
$age = 25;

$errors = [];

if (empty($name)) {
    $errors[] = "姓名不能为空";
} elseif (strlen($name) < 2) {
    $errors[] = "姓名长度不能少于2个字符";
}

if (empty($email)) {
    $errors[] = "邮箱不能为空";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = "邮箱格式不正确";
}

if (empty($age)) {
    $errors[] = "年龄不能为空";
} elseif (!is_numeric($age) || $age < 0 || $age > 150) {
    $errors[] = "年龄必须是0-150之间的数字";
}

if (empty($errors)) {
    echo "表单验证通过!<br>";
} else {
    echo "表单验证失败:<br>";
    foreach ($errors as $error) {
        echo "- $error<br>";
    }
}
?>

switch 语句

基本语法

switch (表达式) {
    case 值1:
        // 当表达式等于值1时执行的代码
        break;
    case 值2:
        // 当表达式等于值2时执行的代码
        break;
    // 更多 case...
    default:
        // 当表达式不匹配任何 case 时执行的代码
        break;
}

语法说明

  • 表达式:可以是任何可以转换为整型或字符串的表达式
  • case:每个 case 后面跟着一个要比较的值
  • break:用于跳出 switch 结构,如果没有 break,会继续执行下一个 case
  • default:可选的,用于处理不匹配任何 case 的情况

基础示例

<?php
// 星期几的显示
$dayOfWeek = 3;
$dayName = '';

switch ($dayOfWeek) {
    case 1:
        $dayName = '星期一';
        break;
    case 2:
        $dayName = '星期二';
        break;
    case 3:
        $dayName = '星期三';
        break;
    case 4:
        $dayName = '星期四';
        break;
    case 5:
        $dayName = '星期五';
        break;
    case 6:
        $dayName = '星期六';
        break;
    case 7:
        $dayName = '星期日';
        break;
    default:
        $dayName = '无效的星期数字';
        break;
}

echo "今天是:$dayName<br>";

// 简单计算器示例
$operator = '+';
$a = 10;
$b = 5;
$result = 0;

switch ($operator) {
    case '+':
        $result = $a + $b;
        echo "$a + $b = $result<br>";
        break;
    case '-':
        $result = $a - $b;
        echo "$a - $b = $result<br>";
        break;
    case '*':
        $result = $a * $b;
        echo "$a * $b = $result<br>";
        break;
    case '/':
        if ($b != 0) {
            $result = $a / $b;
            echo "$a / $b = $result<br>";
        } else {
            echo "错误:除数不能为零!<br>";
        }
        break;
    default:
        echo "不支持的运算符:$operator<br>";
        break;
}
?>

高级 switch 特性

1. 多个 case 共同代码块

<?php
// 季节判断
$month = 8;

switch ($month) {
    case 12:
    case 1:
    case 2:
        $season = '冬季';
        break;
    case 3:
    case 4:
    case 5:
        $season = '春季';
        break;
    case 6:
    case 7:
    case 8:
        $season = '夏季';
        break;
    case 9:
    case 10:
    case 11:
        $season = '秋季';
        break;
    default:
        $season = '无效的月份';
        break;
}

echo "月份 $month 属于$season<br>";
?>

2. 字符串匹配

<?php
// HTTP 状态码处理
$statusCode = 404;

switch ($statusCode) {
    case 200:
        $message = '请求成功';
        break;
    case 301:
    case 302:
        $message = '重定向';
        break;
    case 400:
        $message = '请求错误';
        break;
    case 401:
        $message = '未授权访问';
        break;
    case 403:
        $message = '禁止访问';
        break;
    case 404:
        $message = '页面未找到';
        break;
    case 500:
        $message = '服务器内部错误';
        break;
    default:
        $message = '未知状态码';
        break;
}

echo "HTTP状态码 $statusCode: $message<br>";

// 菜单系统示例
$menuChoice = '2';

switch ($menuChoice) {
    case '1':
        echo "用户管理<br>";
        // 用户管理相关代码
        break;
    case '2':
        echo "商品管理<br>";
        // 商品管理相关代码
        break;
    case '3':
        echo "订单管理<br>";
        // 订单管理相关代码
        break;
    case '4':
        echo "系统设置<br>";
        // 系统设置相关代码
        break;
    case 'q':
    case 'quit':
    case 'exit':
        echo "退出系统<br>";
        break;
    default:
        echo "无效选择,请重新输入<br>";
        break;
}
?>

实际应用场景

1. 用户登录验证系统

<?php
// 模拟用户登录验证系统
function validateLogin($username, $password, $remember = false) {
    // 预定义用户数据(实际应用中应该从数据库读取)
    $users = [
        'admin' => [
            'password' => 'admin123',
            'role' => 'admin',
            'status' => 'active'
        ],
        'user1' => [
            'password' => 'user123',
            'role' => 'user',
            'status' => 'active'
        ]
    ];

    // 验证用户名
    if (empty($username)) {
        return ['success' => false, 'message' => '用户名不能为空'];
    }

    // 验证密码
    if (empty($password)) {
        return ['success' => false, 'message' => '密码不能为空'];
    }

    // 检查用户是否存在
    if (!isset($users[$username])) {
        return ['success' => false, 'message' => '用户名不存在'];
    }

    // 获取用户信息
    $user = $users[$username];

    // 检查用户状态
    if ($user['status'] !== 'active') {
        return ['success' => false, 'message' => '账号已被禁用'];
    }

    // 验证密码
    if ($user['password'] !== $password) {
        return ['success' => false, 'message' => '密码错误'];
    }

    // 登录成功,根据角色设置会话
    switch ($user['role']) {
        case 'admin':
            $permissions = ['read', 'write', 'delete', 'manage_users'];
            break;
        case 'user':
            $permissions = ['read', 'write'];
            break;
        default:
            $permissions = [];
            break;
    }

    return [
        'success' => true,
        'message' => '登录成功',
        'user' => [
            'username' => $username,
            'role' => $user['role'],
            'permissions' => $permissions
        ],
        'remember' => $remember
    ];
}

// 测试登录功能
$result = validateLogin('admin', 'admin123', true);

if ($result['success']) {
    echo "✅ 登录成功<br>";
    echo "角色:{$result['user']['role']}<br>";
    echo "权限:" . implode(', ', $result['user']['permissions']) . "<br>";
} else {
    echo "❌ 登录失败:{$result['message']}<br>";
}
?>

2. 表单处理系统

<?php
// 完整的表单验证和处理系统
function processRegistrationForm($data) {
    $errors = [];

    // 验证用户名
    if (empty($data['username'])) {
        $errors['username'] = '用户名不能为空';
    } elseif (strlen($data['username']) < 3) {
        $errors['username'] = '用户名长度不能少于3个字符';
    } elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $data['username'])) {
        $errors['username'] = '用户名只能包含字母、数字和下划线';
    }

    // 验证邮箱
    if (empty($data['email'])) {
        $errors['email'] = '邮箱不能为空';
    } elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = '邮箱格式不正确';
    }

    // 验证密码
    if (empty($data['password'])) {
        $errors['password'] = '密码不能为空';
    } elseif (strlen($data['password']) < 6) {
        $errors['password'] = '密码长度不能少于6个字符';
    }

    // 如果没有错误,处理注册
    if (empty($errors)) {
        // 根据用户类型设置默认权限
        $userType = $data['user_type'] ?? 'regular';
        switch ($userType) {
            case 'premium':
                $permissions = ['read', 'write', 'upload', 'download'];
                break;
            case 'business':
                $permissions = ['read', 'write', 'upload', 'download', 'api_access'];
                break;
            case 'regular':
            default:
                $permissions = ['read', 'write'];
                break;
        }

        return [
            'success' => true,
            'message' => '注册成功!',
            'user_data' => [
                'username' => $data['username'],
                'email' => $data['email'],
                'user_type' => $userType,
                'permissions' => $permissions
            ]
        ];
    } else {
        return [
            'success' => false,
            'message' => '注册失败,请检查以下错误',
            'errors' => $errors
        ];
    }
}

// 测试表单处理
$testFormData = [
    'username' => 'testuser123',
    'email' => 'test@example.com',
    'password' => 'Password123',
    'user_type' => 'premium'
];

$result = processRegistrationForm($testFormData);

if ($result['success']) {
    echo "🎉 注册成功!<br>";
    echo "用户名:{$result['user_data']['username']}<br>";
    echo "邮箱:{$result['user_data']['email']}<br>";
    echo "用户类型:{$result['user_data']['user_type']}<br>";
    echo "权限:" . implode(', ', $result['user_data']['permissions']) . "<br>";
} else {
    echo "❌ 注册失败!<br>";
    echo "错误信息:<br>";
    foreach ($result['errors'] as $field => $error) {
        echo "- $field: $error<br>";
    }
}
?>

最佳实践

1. 条件语句的选择原则

<?php
// 什么时候使用 if-else vs switch

// ✅ 推荐:复杂条件使用 if-elseif-else
function checkUserPermissions($user, $resource, $action) {
    if (!$user) {
        return false; // 用户未登录
    }

    if ($user['status'] !== 'active') {
        return false; // 用户被禁用
    }

    // 根据用户角色和操作类型判断权限
    if ($user['role'] === 'admin') {
        return true; // 管理员有所有权限
    } elseif ($user['role'] === 'editor') {
        if ($action === 'read' || $action === 'write') {
            return true;
        }
    }

    return false;
}

// ✅ 推荐:简单值匹配使用 switch
function getFileTypeIcon($extension) {
    switch (strtolower($extension)) {
        case 'jpg':
        case 'jpeg':
        case 'png':
        case 'gif':
            return 'image-icon.png';
        case 'pdf':
            return 'pdf-icon.png';
        case 'doc':
        case 'docx':
            return 'word-icon.png';
        default:
            return 'file-icon.png';
    }
}
?>

2. 代码风格建议

<?php
// ✅ 推荐:使用 Yoda 条件(常量在左)
if (5 === $score) {  // 而不是 $score === 5
    // 这样如果忘记写等号会报语法错误,而不是赋值
}

// ✅ 推荐:总是使用花括号
if ($condition) {
    doSomething();
}
// 即使只有一行代码也使用花括号

// ✅ 推荐:早期返回
function processUserData($data) {
    if (empty($data)) {
        return null;  // 早期返回,减少嵌套
    }

    if (!isset($data['id'])) {
        return null;
    }

    // 主要处理逻辑
    return processData($data);
}

// ✅ 推荐:使用严格比较
if ($value === 0) {    // 严格比较
    // 只在值确实是 0 时执行
}

if ($value == 0) {     // 宽松比较
    // 在值为 0、"0"、false、null、"" 时都执行
}
?>

常见错误和解决方案

1. 忘记 break 语句

<?php
// ❌ 错误:忘记 break
$day = 2;
switch ($day) {
    case 1:
        echo "周一";
    case 2:
        echo "周二";  // 会输出 "周二周三周四..."
    case 3:
        echo "周三";
    // 缺少 break,导致继续执行
}

// ✅ 正确:每个 case 都有 break
switch ($day) {
    case 1:
        echo "周一";
        break;
    case 2:
        echo "周二";
        break;
    case 3:
        echo "周三";
        break;
}

// ✅ 特殊情况:故意不使用 break(多个 case 共同代码)
switch ($month) {
    case 12:
    case 1:
    case 2:
        echo "冬季";
        break;
    case 3:
    case 4:
    case 5:
        echo "春季";
        break;
}
?>

2. 赋值与比较混淆

<?php
// ❌ 错误:使用赋值而不是比较
$value = 5;
if ($value = 10) {  // 这里是赋值,不是比较
    echo "值为 10";  // 总是会执行
}

// ✅ 正确:使用比较运算符
if ($value == 10) {
    echo "值为 10";
}

// ✅ 最佳:使用 Yoda 条件避免这种错误
if (10 === $value) {
    echo "值为 10";
    // 如果写成 10 = $value 会报语法错误
}
?>

练习题

基础练习

  1. 成绩等级转换

    <?php
    // 练习:将以下分数转换为等级
    $scores = [95, 85, 75, 65, 45];
    
    // 要求:
    // 90-100: A (优秀)
    // 80-89:  B (良好)
    // 70-79:  C (中等)
    // 60-69:  D (及格)
    // 0-59:   F (不及格)
    
    // 请完成代码...
    ?>
    
  2. 闰年判断

    <?php
    // 练习:判断给定年份是否为闰年
    $years = [2000, 2020, 2021, 2024, 2100];
    
    // 闰年规则:
    // 1. 能被4整除但不能被100整除,或者
    // 2. 能被400整除
    
    // 请完成代码...
    ?>
    
  3. 时间段判断

    <?php
    // 练习:根据当前时间输出问候语
    $hour = date('H'); // 获取当前小时 (0-23)
    
    // 要求:
    // 5-12: 早上好
    // 12-18:下午好
    // 18-22:晚上好
    // 22-5:  夜深了,注意休息
    
    // 请完成代码...
    ?>
    

进阶练习

  1. BMI计算器

    <?php
    // 练习:计算BMI并给出健康建议
    function calculateBMI($weight, $height) {
        // BMI = weight(kg) / height(m)^2
    
        // 要求:
        // < 18.5: 偏瘦
        // 18.5-23.9: 正常
        // 24-27.9: 偏胖
        // >= 28: 肥胖
    
        // 根据BMI值给出健康建议
        // 请完成代码...
    }
    ?>
    
  2. 贷款审批系统

    <?php
    // 练习:实现简单的贷款审批系统
    function approveLoan($age, $income, $creditScore, $employmentYears) {
        // 审批规则:
        // 1. 年龄必须在 22-60 岁之间
        // 2. 收入必须 > 5000
        // 3. 信用分必须 > 600
        // 4. 工作年限必须 > 1年
    
        // 返回数组包含:approved, amount, rate, reason
        // 请完成代码...
    }
    ?>
    

总结

条件语句是PHP编程中的基础控制结构,掌握好条件语句对于编写高质量的PHP代码至关重要。以下是关键要点:

核心概念

  1. if 语句:单一条件判断
  2. if-else 语句:二选一判断
  3. if-elseif-else 语句:多重条件判断
  4. switch 语句:多值匹配判断

选择建议

  • 复杂条件:使用 if-elseif-else
  • 简单值匹配:使用 switch
  • 布尔条件:使用 if-else
  • 性能考虑:将最可能的条件放在前面

最佳实践

  1. 使用严格比较 (=== 而不是 ==)
  2. 总是使用花括号包围代码块
  3. 使用 Yoda 条件避免赋值错误
  4. 合理使用早期返回简化嵌套

常见陷阱

  1. 忘记 switch 中的 break
  2. 混淆赋值和比较运算符
  3. 忽略类型转换的影响
  4. 错误的逻辑运算符优先级

通过大量的练习和实际应用,您将能够熟练运用条件语句来解决各种编程问题。下一章我们将学习循环语句,让程序能够重复执行代码块。