PHP 零基础教程

PHP 比较与逻辑运算符

比较运算符和逻辑运算符是控制 PHP 脚本执行流程的基础。它们允许脚本根据值之间的关系和多个条件的真假来做出“决策”。

1. 比较运算符 (Comparison Operators)

比较运算符用于比较两个值,并返回一个布尔结果:true(真)或 false(假)。这些运算符是条件语句的核心,使得代码只有在满足特定标准时才会执行。

1.1 相等与全等 (Equality and Identity)

PHP 提供了两种主要的方式来检查相等性:松散相等 (==) 和严格全等 (===)。

松散相等 (==): 该运算符在进行比较之前,如果必要的话,会先执行隐式类型转换 (Type Juggling)。如果两个值的类型不同,PHP 会尝试将它们转换为相同的类型然后再进行比较。

<?php
$num1 = 10;
$str1 = "10";
$bool1 = true;
$strBool = "true";

// 示例 1:整数 vs 字符串 (发生隐式转换)
var_dump($num1 == $str1); // 输出:bool(true) - 字符串 "10" 被转换成了整数 10

// 示例 2:整数 vs 布尔值 (发生隐式转换)
var_dump($num1 == $bool1); // 输出:bool(false) - 10 不等于 1 (true 转换成整数是 1)

// 示例 3:字符串 vs 布尔值 (发生隐式转换)
var_dump($strBool == $bool1); // 输出:bool(true) - 非空字符串 "true" 在布尔上下文中被视为 true
?>

在第一个例子中,整数 10 和字符串 "10" 是松散相等的,因为 PHP 在比较前把字符串 "10" 变成了整数。

严格全等 (===): 该运算符检查两个值是否相等 并且 数据类型也相同。它不会执行任何类型转换。在绝大多数情况下,为了保证精确比较,强烈推荐使用严格全等。

<?php
$num2 = 20;
$str2 = "20";
$bool2 = true;
$intTrue = 1;

// 示例 1:整数 vs 字符串 (类型不同)
var_dump($num2 === $str2); // 输出:bool(false) - 数据类型 (int vs string) 不全等

// 示例 2:整数 vs 布尔值 (类型不同)
var_dump($num2 === $bool2); // 输出:bool(false) - 数据类型 (int vs bool) 不全等

// 示例 3:整数 1 vs 布尔值 true (类型不同)
var_dump($intTrue === $bool2); // 输出:bool(false) - 数据类型 (int vs bool) 不全等
?>

使用 === 可以防止因 PHP 自动类型转换而导致的意外行为,确保比较在“值”和“类型”上都是绝对精确的。

1.2 不等 (Inequality)

与相等类似,也有松散不等 (!=<>) 和严格不全等 (!==) 运算符。

松散不等 (!=<>): 如果在类型转换后两个值不相等,则返回 true<> 只是 != 的另一种写法,两者功能完全一样。

<?php
$valA = 5;
$valB = "5";
$valC = 7;

// 示例 1:整数 vs 字符串 (松散不等)
var_dump($valA != $valB); // 输出:bool(false) - 因为 5 == "5" 是 true,所以 5 != "5" 就是 false

// 示例 2:整数 vs 整数
var_dump($valA != $valC); // 输出:bool(true) - 5 不等于 7
?>

严格不全等 (!==): 如果两个值不相等,或者它们的数据类型不同,则返回 true

<?php
$valD = 100;
$valE = "100";
$valF = 101;

// 示例 1:整数 vs 字符串 (严格不全等)
var_dump($valD !== $valE); // 输出:bool(true) - 虽然值看起来一样,但数据类型不同

// 示例 2:整数 vs 整数 (值不同)
var_dump($valD !== $valF); // 输出:bool(true) - 值本身就不相等
?>

1.3 大于、小于及组合

这些运算符用于比较数值的大小。

  • 大于 (>): 如果左操作数大于右操作数,返回 true
  • 小于 (<): 如果左操作数小于右操作数,返回 true
  • 大于等于 (>=): 如果左操作数大于或等于右操作数,返回 true
  • 小于等于 (<=): 如果左操作数小于或等于右操作数,返回 true
<?php
$score = 85;
$passingGrade = 70;
$maxScore = 100;

// 大于
var_dump($score > $passingGrade); // 输出:bool(true) - 85 大于 70

// 小于
var_dump($score < $passingGrade); // 输出:bool(false) - 85 不小于 70

// 大于等于
var_dump($score >= $passingGrade); // 输出:bool(true) - 85 大于或等于 70
var_dump($passingGrade >= 70);    // 输出:bool(true) - 70 等于 70 (满足条件)

// 小于等于
var_dump($score <= $maxScore);    // 输出:bool(true) - 85 小于 100
var_dump($score <= 85);           // 输出:bool(true) - 85 等于 85 (满足条件)
?>

1.4 太空船运算符 (<=>)

太空船运算符 (<=>) 是 PHP 7 引入的,它是一个三向比较运算符。它会返回:

  • 0:如果两边的操作数相等。
  • 1:如果左边的操作数更大。
  • -1:如果右边的操作数更大。

这个运算符在编写排序函数或你需要同时知道两个值是否相等以及谁大谁小时非常有用。

<?php
$a = 5;
$b = 10;
$c = 5;

var_dump($a <=> $b); // 输出:int(-1) - 因为 $a 小于 $b
var_dump($b <=> $a); // 输出:int(1)  - 因为 $b 大于 $a
var_dump($a <=> $c); // 输出:int(0)  - 因为 $a 等于 $c

// 它也支持字符串(按字典顺序/字母表顺序比较)
$strX = "apple";
$strY = "banana";
$strZ = "apple";

var_dump($strX <=> $strY); // 输出:int(-1) - 'a' 在 'b' 前面
var_dump($strY <=> $strX); // 输出:int(1)
var_dump($strX <=> $strZ); // 输出:int(0)
?>

2. 逻辑运算符 (Logical Operators)

逻辑运算符用于组合或修改布尔表达式。它们通过评估多个比较结果的真假,来构建更复杂的条件。

2.1 逻辑与 (AND) 运算符 (&&and)

AND 运算符要求所有操作数都必须为 true,结果才返回 true。如果任何一个操作数为 false,结果就是 false

  • 逻辑与 (&&): 这是最常用的 AND 运算符,它的优先级高于 and
  • 逻辑 and (and): 优先级低于 &&。在日常开发中,通常推荐使用 &&
<?php
$age = 25;
$isStudent = true;
$hasLicense = false;

// 使用 &&
// 条件:年龄在 18 到 30 之间,并且是一名学生
var_dump($age >= 18 && $age <= 30 && $isStudent); // 输出:bool(true)
                                                 // (true && true && true) -> true

// 条件:年龄大于 18,并且拥有驾照
var_dump($age > 18 && $hasLicense);              // 输出:bool(false)
                                                 // (true && false) -> false

// 使用 'and' (展示优先级差异)
// $canVote = $age >= 18 and $hasLicense; 
// 注意:上面这行代码,赋值运算符 '=' 的优先级高于 'and',所以 $canVote 会先被赋值为 ($age >= 18) 的结果!

// 正确的使用方式通常需要加括号:
$canVote = ($age >= 18 and $hasLicense); 
var_dump($canVote); // 输出:bool(false)
?>

由于优先级陷阱,对于通用的条件检查,强烈建议标准化使用 &&

2.2 逻辑或 (OR) 运算符 (||or)

OR 运算符只要有至少一个操作数为 true,结果就返回 true。只有当所有操作数都为 false 时,结果才为 false

  • 逻辑或 (||): 最常用的 OR 运算符,优先级高于 or
  • 逻辑 or (or): 优先级低于 ||
<?php
$temperature = 28;
$isRaining = false;
$isSunny = true;

// 使用 ||
// 条件:温度超过 25 度,或者正在下雨
var_dump($temperature > 25 || $isRaining); // 输出:bool(true)
                                          // (true || false) -> true

// 条件:正在下雨,或者是晴天
var_dump($isRaining || $isSunny);         // 输出:bool(true)
                                          // (false || true) -> true

// 条件:温度低于 0 度,或者正在下雨 (两者都不满足)
var_dump($temperature < 0 || $isRaining); // 输出:bool(false)
                                          // (false || false) -> false
?>

与 AND 类似,通常推荐使用 || 而不是 or

2.3 逻辑异或 (XOR) 运算符 (xor)

XOR(异或)运算符要求有且仅有一个操作数为 true 时,结果才返回 true。如果两个都为 true,或者两个都为 false,结果都是 false

<?php
$condition1 = true;
$condition2 = false;
$condition3 = true;

// 示例 1:一真一假
var_dump($condition1 xor $condition2); // 输出:bool(true)

// 示例 2:两真
var_dump($condition1 xor $condition3); // 输出:bool(false)

// 示例 3:两假 (假设 $age = 25,($age < 18) 为 false)
var_dump($condition2 xor ($age < 18)); // 输出:bool(false)
?>

2.4 逻辑非 (NOT) 运算符 (!)

NOT 运算符(逻辑取反)会反转其操作数的布尔值。如果操作数是 true! 就会把它变成 false;反之亦然。

<?php
$isLoggedIn = false;
$isAdmin = true;

// 示例 1:对 false 取反
var_dump(!$isLoggedIn); // 输出:bool(true) - !false 等于 true

// 示例 2:对 true 取反
var_dump(!$isAdmin);    // 输出:bool(false) - !true 等于 false

// 示例 3:对比较表达式取反 (假设 $age = 25,($age > 30) 为 false)
var_dump(!($age > 30)); // 输出:bool(true) - !false 等于 true
?>

3. 综合实战案例与演示

让我们结合比较和逻辑运算符来构建更复杂的条件,这在 Web 开发场景(如用户输入验证或权限检查)中非常常见。

3.1 用户身份认证检查

想象一个用户尝试登录的场景。我们需要检查他们输入的用户名和密码是否与数据库中存储的信息完全匹配。

<?php
$inputUsername = "admin_user";
$inputPassword = "securePassword123";

$storedUsername = "admin_user";
$storedPassword = "securePassword123";
$isAccountActive = true;

// 检查用户名、密码是否严格匹配,并且账户处于激活状态
if (($inputUsername === $storedUsername) && ($inputPassword === $storedPassword) && $isAccountActive) {
    echo "登录成功!欢迎," . $inputUsername . "。\n";
} else {
    echo "登录失败。请检查您的凭据或账户状态。\n";
}

// 场景 2:密码不正确
$inputPassword2 = "wrongPassword";
if (($inputUsername === $storedUsername) && ($inputPassword2 === $storedPassword) && $isAccountActive) {
    echo "这行不会被打印。\n";
} else {
    echo "使用错误密码 ('wrongPassword') 登录失败。\n"; // 这行会被打印
}
?>

此示例使用严格全等 (===) 进行精确的凭证比较,并使用逻辑与 (&&) 确保只有在所有条件(用户名匹配、密码匹配、账户激活)同时满足时,才允许成功登录。

3.2 在线订单表单验证

考虑一个在线商店的表单,用户在其中订购产品。我们可能有如下业务条件:

  1. 购买数量必须是正整数。
  2. 配送偏好必须是“标准 (standard)”或“加急 (express)”。
  3. 如果选择了“加急”配送,订单总额必须至少达到 $50。
<?php
$quantity = 3;
$deliveryPreference = "express";
$orderTotal = 65.50; // 假设这是计算出的总价

// 条件 1:数量有效(大于 0 且是整数类型)
$isValidQuantity = ($quantity > 0 && is_int($quantity)); // is_int() 是 PHP 内置函数,检查变量是否为整数

// 条件 2:配送偏好有效
$isValidDeliveryPreference = ($deliveryPreference === "standard" || $deliveryPreference === "express");

// 条件 3:如果选择了加急,检查订单总额
$isExpressEligible = true; // 默认符合条件
if ($deliveryPreference === "express") {
    $isExpressEligible = ($orderTotal >= 50); // 如果金额不够 50,这里会变成 false
}

// 使用逻辑运算符组合所有条件
if ($isValidQuantity && $isValidDeliveryPreference && $isExpressEligible) {
    echo "订单详情有效,可以继续处理。\n";
} else {
    echo "订单验证失败。请检查您的输入。\n";
    if (!$isValidQuantity) {
        echo "- 数量必须是正整数。\n";
    }
    if (!$isValidDeliveryPreference) {
        echo "- 无效的配送选项。\n";
    }
    if (!$isExpressEligible) {
        echo "- 选择加急配送需要最低订单总额达到 $50。\n";
    }
}
?>

这个全面的示例演示了如何组合比较运算符(>,===,>=)和逻辑运算符(&&,||,!)来处理验证用户输入的多个业务标准。