运算符

什么是运算符?

在编程中,运算符是用于执行特定数学或逻辑操作的符号。PHP提供了丰富的运算符,可以对不同类型的数据进行各种操作。

运算符的基本组成部分:

  • 操作数:参与运算的数据(变量、常量或字面值)
  • 运算符:执行操作的符号(如 +-*/
  • 表达式:运算符和操作数的组合,产生一个值

例如,在表达式 2 + 3 中:

  • 23 是操作数
  • + 是运算符
  • 2 + 3 是表达式,结果为 5

PHP运算符分类

PHP的运算符可以分为以下几大类:

  1. 算术运算符:执行数学计算
  2. 赋值运算符:给变量赋值
  3. 比较运算符:比较两个值
  4. 逻辑运算符:执行布尔逻辑操作
  5. 字符串运算符:连接字符串
  6. 数组运算符:比较和组合数组
  7. 位运算符:对二进制位进行操作
  8. 其他运算符:三元运算符、错误控制等

算术运算符

算术运算符用于执行基本的数学运算。

基本算术运算符

<?php
$a = 10;
$b = 3;

echo "加法:{$a} + {$b} = " . ($a + $b) . "<br>";        // 输出:13
echo "减法:{$a} - {$b} = " . ($a - $b) . "<br>";        // 输出:7
echo "乘法:{$a} * {$b} = " . ($a * $b) . "<br>";        // 输出:30
echo "除法:{$a} / {$b} = " . ($a / $b) . "<br>";        // 输出:3.3333333333333
echo "取余:{$a} % {$b} = " . ($a % $b) . "<br>";        // 输出:1
echo "幂运算:{$a} ** {$b} = " . ($a ** $b) . "<br>";    // 输出:1000(PHP 5.6+)

// 注意除法的返回值类型
$divResult = 10 / 2;        // 结果:5.0(浮点数)
$divResult2 = 11 / 2;       // 结果:5.5(浮点数)
echo gettype($divResult);   // 输出:double

// 取余运算的特殊情况
echo "10 % 3 = " . (10 % 3) . "<br>";      // 输出:1
echo "10 % -3 = " . (10 % -3) . "<br>";     // 输出:1
echo "-10 % 3 = " . (-10 % 3) . "<br>";     // 输出:-1
echo "-10 % -3 = " . (-10 % -3) . "<br>";    // 输出:-1
?>

算术运算符的实际应用

<?php
// 计算购物车总价
class ShoppingCart {
    private $items = [];
    private $taxRate = 0.08; // 8% 税率

    public function addItem($name, $price, $quantity = 1) {
        $this->items[] = [
            'name' => $name,
            'price' => $price,
            'quantity' => $quantity
        ];
    }

    public function getSubtotal() {
        $subtotal = 0;
        foreach ($this->items as $item) {
            $subtotal += $item['price'] * $item['quantity'];
        }
        return $subtotal;
    }

    public function getTax() {
        return $this->getSubtotal() * $this->taxRate;
    }

    public function getTotal() {
        return $this->getSubtotal() + $this->getTax();
    }

    public function displayCart() {
        echo "<h3>购物车详情</h3>";
        echo "<table border='1'>";
        echo "<tr><th>商品</th><th>单价</th><th>数量</th><th>小计</th></tr>";

        foreach ($this->items as $item) {
            $subtotal = $item['price'] * $item['quantity'];
            echo "<tr>";
            echo "<td>{$item['name']}</td>";
            echo "<td>¥{$item['price']}</td>";
            echo "<td>{$item['quantity']}</td>";
            echo "<td>¥{$subtotal}</td>";
            echo "</tr>";
        }

        echo "</table>";
        echo "<p>小计:¥{$this->getSubtotal()}</p>";
        echo "<p>税费:¥{$this->getTax()}</p>";
        echo "<p><strong>总计:¥{$this->getTotal()}</strong></p>";
    }
}

// 使用购物车
$cart = new ShoppingCart();
$cart->addItem("苹果", 5.50, 3);      // 3个苹果,每个5.5元
$cart->addItem("香蕉", 3.20, 2);      // 2根香蕉,每根3.2元
$cart->addItem("橙子", 8.00, 1);      // 1个橙子,8元

$cart->displayCart();

// 面积计算示例
function calculateCircleArea($radius) {
    return pi() * $radius ** 2;  // π * r²
}

function calculateRectangleArea($length, $width) {
    return $length * $width;
}

function calculateTriangleArea($base, $height) {
    return $base * $height / 2;   // (base * height) / 2
}

echo "<h3>面积计算</h3>";
echo "半径为5的圆面积:" . calculateCircleArea(5) . "<br>";
echo "长为10宽为6的矩形面积:" . calculateRectangleArea(10, 6) . "<br>";
echo "底为8高为4的三角形面积:" . calculateTriangleArea(8, 4) . "<br>";
?>

赋值运算符

赋值运算符用于给变量赋值,PHP提供了多种赋值运算符。

基本赋值运算符

<?php
// 基本赋值
$x = 10;
$y = "Hello";
$z = true;

// 链式赋值
$a = $b = $c = 5;  // a、b、c 都等于 5
echo "a = {$a}, b = {$b}, c = {$c}<br>";

// 复合赋值运算符
$num = 10;
$num += 5;      // 等同于 $num = $num + 5,结果:15
echo "加法赋值:{$num}<br>";

$num -= 3;      // 等同于 $num = $num - 3,结果:12
echo "减法赋值:{$num}<br>";

$num *= 2;      // 等同于 $num = $num * 2,结果:24
echo "乘法赋值:{$num}<br>";

$num /= 4;      // 等同于 $num = $num / 4,结果:6
echo "除法赋值:{$num}<br>";

$num %= 4;      // 等同于 $num = $num % 4,结果:2
echo "取余赋值:{$num}<br>";

// 字符串连接赋值
$text = "Hello";
$text .= " World";     // 等同于 $text = $text . " World"
echo "字符串连接赋值:{$text}<br>";

// 幂运算赋值(PHP 5.6+)
$power = 2;
$power **= 3;          // 等同于 $power = $power ** 3,结果:8
echo "幂运算赋值:{$power}<br>";

// 位运算赋值
$bits = 5;             // 二进制:101
$bits &= 3;            // 等同于 $bits = $bits & 3,结果:1(001)
echo "位与赋值:{$bits}<br>";

$bits = 5;             // 重置为 5(101)
$bits |= 2;            // 等同于 $bits = $bits | 2,结果:7(111)
echo "位或赋值:{$bits}<br>";

$bits = 5;             // 重置为 5(101)
$bits ^= 3;            // 等同于 $bits = $bits ^ 3,结果:6(110)
echo "位异或赋值:{$bits}<br>";

$bits = 5;             // 重置为 5(101)
$bits <<= 1;           // 等同于 $bits = $bits << 1,结果:10(1010)
echo "左移赋值:{$bits}<br>";

$bits = 5;             // 重置为 5(101)
$bits >>= 1;           // 等同于 $bits = $bits >> 1,结果:2(10)
echo "右移赋值:{$bits}<br>";
?>

赋值运算符的实际应用

<?php
// 游戏角色属性更新
class GameCharacter {
    private $name;
    private $level = 1;
    private $experience = 0;
    private $health = 100;
    private $maxHealth = 100;
    private $gold = 0;

    public function __construct($name) {
        $this->name = $name;
    }

    public function gainExperience($amount) {
        $this->experience += $amount;

        // 检查是否升级(每100经验升1级)
        while ($this->experience >= $this->level * 100) {
            $this->levelUp();
        }
    }

    private function levelUp() {
        $this->level++;
        $this->maxHealth += 20;
        $this->health = $this->maxHealth;  // 升级时恢复满血
        echo "{$this->name} 升级了!当前等级:{$this->level}<br>";
    }

    public function takeDamage($damage) {
        $this->health -= $damage;
        if ($this->health < 0) {
            $this->health = 0;
        }
        echo "{$this->name} 受到 {$damage} 点伤害,剩余血量:{$this->health}<br>";
    }

    public function heal($amount) {
        $this->health += $amount;
        if ($this->health > $this->maxHealth) {
            $this->health = $this->maxHealth;
        }
        echo "{$this->name} 恢复了 {$amount} 点血量,当前血量:{$this->health}<br>";
    }

    public function earnGold($amount) {
        $this->gold += $amount;
        echo "{$this->name} 获得了 {$amount} 金币,总金币:{$this->gold}<br>";
    }

    public function spendGold($amount) {
        if ($this->gold >= $amount) {
            $this->gold -= $amount;
            echo "{$this->name} 花费了 {$amount} 金币,剩余金币:{$this->gold}<br>";
            return true;
        } else {
            echo "金币不足!需要 {$amount} 金币,当前只有 {$this->gold} 金币<br>";
            return false;
        }
    }

    public function getStatus() {
        return [
            'name' => $this->name,
            'level' => $this->level,
            'experience' => $this->experience,
            'health' => $this->health,
            'maxHealth' => $this->maxHealth,
            'gold' => $this->gold
        ];
    }
}

// 游戏模拟
$hero = new GameCharacter("勇者");

// 战斗和成长
$hero->earnGold(50);        // 获得金币
$hero->gainExperience(120); // 获得经验,会升级到2级
$hero->takeDamage(30);      // 受到伤害
$hero->heal(20);           // 治疗
$hero->gainExperience(200); // 再获得经验,升级到3级
$hero->earnGold(100);       // 再获得金币

// 购买物品
$hero->spendGold(80);       // 成功购买
$hero->spendGold(100);      // 金币不足

// 显示最终状态
$status = $hero->getStatus();
echo "<h3>角色状态</h3>";
foreach ($status as $key => $value) {
    echo "<strong>{$key}:</strong> {$value}<br>";
}
?>

比较运算符

比较运算符用于比较两个值,返回布尔值(true 或 false)。

基本比较运算符

<?php
$a = 10;
$b = "10";
$c = 5;
$d = "hello";

// 等于比较(==)- 只比较值,不比较类型
var_dump($a == $b);    // bool(true) - 10等于"10"
var_dump($a == $c);    // bool(false) - 10不等于5

// 全等于比较(===)- 值和类型都比较
var_dump($a === $b);   // bool(false) - 整数10不等于字符串"10"
var_dump($a === 10);   // bool(true) - 值和类型都相同

// 不等于比较(!=)
var_dump($a != $c);    // bool(true) - 10不等于5

// 不全等于比较(!==)
var_dump($a !== $b);   // bool(true) - 10不全等于"10"

// 不等于的其他写法
var_dump($a <> $c);    // bool(true) - 不等于的另一种写法

// 大于比较
var_dump($a > $c);     // bool(true) - 10大于5

// 小于比较
var_dump($a < $c);     // bool(false) - 10不小于5

// 大于等于比较
var_dump($a >= $b);    // bool(true) - 10大于等于"10"
var_dump($a >= 10);    // bool(true) - 10大于等于10

// 小于等于比较
var_dump($a <= $b);    // bool(true) - 10小于等于"10"
var_dump($a <= 5);     // bool(false) - 10不小于等于5

// 字符串比较
var_dump("apple" < "banana");     // bool(true) - 字典序比较
var_dump("zebra" > "apple");      // bool(true)
var_dump("Hello" < "hello");      // bool(true) - 大写字母ASCII码小于小写
var_dump("10" < "2");             // bool(true) - 字符串比较,"1"小于"2"
var_dump("10" < 2);               // bool(false) - 数字比较,10大于2
?>

比较运算符的实际应用

<?php
// 用户年龄验证系统
class UserAgeValidator {
    private $minAge;
    private $maxAge;

    public function __construct($minAge = 18, $maxAge = 120) {
        $this->minAge = $minAge;
        $this->maxAge = $maxAge;
    }

    public function validateAge($age) {
        // 检查是否为数字
        if (!is_numeric($age)) {
            return [
                'valid' => false,
                'message' => '年龄必须是数字'
            ];
        }

        $ageNum = (int)$age;

        // 检查年龄范围
        if ($ageNum < $this->minAge) {
            return [
                'valid' => false,
                'message' => "年龄不能小于 {$this->minAge} 岁"
            ];
        }

        if ($ageNum > $this->maxAge) {
            return [
                'valid' => false,
                'message' => "年龄不能大于 {$this->maxAge} 岁"
            ];
        }

        return [
            'valid' => true,
            'message' => '年龄验证通过',
            'age' => $ageNum
        ];
    }

    public function getAgeGroup($age) {
        $result = $this->validateAge($age);
        if (!$result['valid']) {
            return '未知';
        }

        $ageNum = $result['age'];

        if ($ageNum < 13) {
            return '儿童';
        } elseif ($ageNum < 20) {
            return '青少年';
        } elseif ($ageNum < 35) {
            return '青年';
        } elseif ($ageNum < 60) {
            return '中年';
        } else {
            return '老年';
        }
    }
}

// 密码强度验证
class PasswordValidator {
    public function validatePassword($password, $confirmPassword = null) {
        $errors = [];
        $strength = 0;

        // 检查长度
        if (strlen($password) < 8) {
            $errors[] = '密码长度至少需要8位';
        } elseif (strlen($password) >= 8) {
            $strength++;
        }

        if (strlen($password) >= 12) {
            $strength++;
        }

        // 检查是否包含数字
        if (preg_match('/[0-9]/', $password)) {
            $strength++;
        } else {
            $errors[] = '密码需要包含至少一个数字';
        }

        // 检查是否包含字母
        if (preg_match('/[a-zA-Z]/', $password)) {
            $strength++;
        } else {
            $errors[] = '密码需要包含至少一个字母';
        }

        // 检查是否包含特殊字符
        if (preg_match('/[!@#$%^&*(),.?":{}|<>]/', $password)) {
            $strength++;
        }

        // 检查确认密码
        if ($confirmPassword !== null) {
            if ($password !== $confirmPassword) {
                $errors[] = '两次输入的密码不一致';
            }
        }

        // 检查是否包含常见弱密码
        $weakPasswords = ['password', '123456', 'qwerty', 'admin', 'letmein'];
        foreach ($weakPasswords as $weak) {
            if (strtolower($password) === $weak) {
                $errors[] = '密码过于简单,请使用更复杂的密码';
                break;
            }
        }

        return [
            'valid' => empty($errors),
            'errors' => $errors,
            'strength' => $strength,
            'strengthText' => $this->getStrengthText($strength)
        ];
    }

    private function getStrengthText($strength) {
        if ($strength <= 2) {
            return '弱';
        } elseif ($strength <= 4) {
            return '中等';
        } else {
            return '强';
        }
    }
}

// 使用示例
echo "<h2>用户验证示例</h2>";

// 年龄验证
$ageValidator = new UserAgeValidator(18, 100);
$testAges = [16, 18, 25, "30", 150, "abc", "25.5"];

echo "<h3>年龄验证测试</h3>";
foreach ($testAges as $age) {
    $result = $ageValidator->validateAge($age);
    $group = $ageValidator->getAgeGroup($age);
    echo "年龄 {$age}: ";
    if ($result['valid']) {
        echo "<span style='color: green;'>{$result['message']}</span>";
        echo ",属于 {$group} 年龄段";
    } else {
        echo "<span style='color: red;'>{$result['message']}</span>";
    }
    echo "<br>";
}

// 密码验证
$passwordValidator = new PasswordValidator();
$testPasswords = [
    'password' => 'password',
    '123456' => '123456',
    'weak' => 'weak',
    'strong123!' => 'strong123!',
    'StrongPass123!' => 'StrongPass123!',
    'mypass123' => 'mypass123'
];

echo "<h3>密码强度测试</h3>";
foreach ($testPasswords as $name => $password) {
    $result = $passwordValidator->validatePassword($password);
    echo "密码 '{$password}': ";
    echo "强度 - <strong>{$result['strengthText']}</strong> ({$result['strength']}/5)";

    if (!$result['valid']) {
        echo ",错误:" . implode(', ', $result['errors']);
    }
    echo "<br>";
}

// 密码确认测试
echo "<h3>密码确认测试</h3>";
$confirmResult = $passwordValidator->validatePassword('Test123!', 'Test123!');
echo "密码匹配测试:";
if ($confirmResult['valid']) {
    echo "<span style='color: green;'>密码匹配</span>";
} else {
    echo "<span style='color: red;'>密码不匹配</span>";
}
echo "<br>";

$mismatchResult = $passwordValidator->validatePassword('Test123!', 'Test456!');
echo "密码不匹配测试:";
if ($mismatchResult['valid']) {
    echo "<span style='color: green;'>密码匹配</span>";
} else {
    echo "<span style='color: red;'>密码不匹配:" . implode(', ', $mismatchResult['errors']) . "</span>";
}
echo "<br>";
?>

逻辑运算符

逻辑运算符用于执行布尔逻辑操作,通常用在条件语句中。

基本逻辑运算符

<?php
$x = true;
$y = false;

// 逻辑与(AND)- 两个都为true时结果为true
$result1 = $x and $y;    // false
$result2 = $x && $y;      // false(优先级更高)

// 逻辑或(OR)- 至少一个为true时结果为true
$result3 = $x or $y;     // true
$result4 = $x || $y;     // true(优先级更高)

// 逻辑异或(XOR)- 两个值不同时为true
$result5 = $x xor $y;    // true

// 逻辑非(NOT)- 取反
$result6 = !$x;          // false
$result7 = !$y;          // true

// 输出结果
var_dump($result1, $result2, $result3, $result4, $result5, $result6, $result7);

// 运算符优先级示例
$a = true;
$b = false;
$c = true;

// and 优先级低于 =
$result = $a and $b or $c;  // 相当于 ($result = $a) and ($b or $c)
var_dump($result);           // true($result被赋值为$a的值true)

// && 优先级高于 =
$result = $a && $b || $c;    // 相当于 $result = ($a && $b) || $c
var_dump($result);           // true

// 推荐使用括号明确优先级
$result = ($a and $b) or $c;
var_dump($result);           // true

$result = ($a && $b) || $c;
var_dump($result);           // true
?>

短路求值

<?php
function getValue($name) {
    echo "调用函数 getValue({$name})<br>";
    return $name === 'good';
}

// 短路求值:如果第一个操作数就能确定结果,不会计算第二个操作数
echo "<h3>逻辑与短路求值</h3>";
$result = getValue('bad') and getValue('good');  // 只调用第一个函数
echo "结果:" . ($result ? 'true' : 'false') . "<br>";

echo "<h3>逻辑或短路求值</h3>";
$result = getValue('good') or getValue('bad');  // 只调用第一个函数
echo "结果:" . ($result ? 'true' : 'false') . "<br>";

echo "<h3>实际应用示例</h3>";

// 安全的数组访问
function getValueSafely($array, $key, $default = null) {
    // 使用 && 短路求值避免 Undefined index 错误
    return (isset($array) && is_array($array) && array_key_exists($key, $array))
           ? $array[$key]
           : $default;
}

$data = ['name' => '张三', 'age' => 25];

echo getValueSafely($data, 'name', '未知') . "<br>";     // 输出:张三
echo getValueSafely($data, 'email', '未知') . "<br>";    // 输出:未知
echo getValueSafely(null, 'name', '未知') . "<br>";      // 输出:未知

// 条件赋值
function getUserInfo($userId) {
    echo "查询用户 {$userId} 的信息<br>";

    // 模拟数据库查询
    $users = [
        1 => ['name' => '张三', 'age' => 25],
        2 => ['name' => '李四', 'age' => 30]
    ];

    return $users[$userId] ?? null;
}

// 使用逻辑或进行条件赋值
$userId = 1;
$user = getUserInfo($userId) or die('用户不存在');
echo "用户姓名:" . $user['name'] . "<br>";

$userId = 3;
// 下面这行会因为短路求值而执行 die()
// $user = getUserInfo($userId) or die('用户不存在');
?>

逻辑运算符的实际应用

<?php
// 用户权限管理系统
class PermissionChecker {
    private $userPermissions;
    private $userRole;

    public function __construct($role, $permissions = []) {
        $this->userRole = $role;
        $this->userPermissions = $permissions;
    }

    public function canAccessPage($page) {
        // 定义页面权限要求
        $pagePermissions = [
            'dashboard' => ['guest', 'user', 'admin'],
            'profile' => ['user', 'admin'],
            'settings' => ['user', 'admin'],
            'admin_panel' => ['admin'],
            'reports' => ['admin', 'manager'],
            'login' => ['all']
        ];

        $requiredPermissions = $pagePermissions[$page] ?? [];

        // 如果页面允许所有角色访问
        if (in_array('all', $requiredPermissions)) {
            return true;
        }

        // 检查用户角色
        return in_array($this->userRole, $requiredPermissions);
    }

    public function canPerformAction($action) {
        // 检查特定权限
        return in_array($action, $this->userPermissions);
    }

    public function canAccessWithConditions($page, $conditions = []) {
        // 基础权限检查
        if (!$this->canAccessPage($page)) {
            return false;
        }

        // 额外条件检查
        foreach ($conditions as $condition => $value) {
            switch ($condition) {
                case 'is_owner':
                    if (!$value) {
                        return false;
                    }
                    break;
                case 'during_business_hours':
                    $hour = (int)date('H');
                    if ($hour < 9 || $hour > 17) {
                        return false;
                    }
                    break;
                case 'has_verified_email':
                    if (!$value) {
                        return false;
                    }
                    break;
            }
        }

        return true;
    }
}

// 表单验证系统
class FormValidator {
    private $errors = [];

    public function validateEmail($email) {
        $isValid = true;
        $message = '';

        // 使用逻辑运算符进行多重验证
        if (empty($email)) {
            $isValid = false;
            $message = '邮箱不能为空';
        } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $isValid = false;
            $message = '邮箱格式不正确';
        } elseif (strlen($email) > 100) {
            $isValid = false;
            $message = '邮箱长度不能超过100个字符';
        }

        if (!$isValid) {
            $this->errors['email'] = $message;
        }

        return $isValid;
    }

    public function validatePassword($password, $confirm = null) {
        $isValid = true;

        // 使用复杂的逻辑条件
        if (empty($password) || strlen($password) < 8) {
            $this->errors['password'] = '密码长度至少需要8位';
            $isValid = false;
        } elseif (!preg_match('/[A-Z]/', $password) || !preg_match('/[a-z]/', $password)) {
            $this->errors['password'] = '密码需要包含大小写字母';
            $isValid = false;
        } elseif (!preg_match('/[0-9]/', $password)) {
            $this->errors['password'] = '密码需要包含数字';
            $isValid = false;
        } elseif ($confirm !== null && $password !== $confirm) {
            $this->errors['password'] = '两次输入的密码不一致';
            $isValid = false;
        }

        return $isValid;
    }

    public function validateUserAge($age) {
        $ageNum = (int)$age;

        // 复杂的年龄验证逻辑
        if (!is_numeric($age)) {
            $this->errors['age'] = '年龄必须是数字';
            return false;
        } elseif ($ageNum < 0 || $ageNum > 150) {
            $this->errors['age'] = '年龄必须在0-150之间';
            return false;
        } elseif ($ageNum < 13) {
            $this->errors['age'] = '用户年龄不能小于13岁';
            return false;
        }

        return true;
    }

    public function validateTerms($accepted) {
        // 验证条款是否被接受
        if (!$accepted || $accepted !== 'on' && $accepted !== true) {
            $this->errors['terms'] = '必须同意服务条款';
            return false;
        }

        return true;
    }

    public function isValid() {
        return empty($this->errors);
    }

    public function getErrors() {
        return $this->errors;
    }
}

// 使用示例
echo "<h2>权限检查示例</h2>";

// 创建不同权限的用户
$guest = new PermissionChecker('guest');
$user = new PermissionChecker('user', ['edit_profile', 'view_reports']);
$admin = new PermissionChecker('admin', ['all']);

// 页面访问测试
$pages = ['dashboard', 'profile', 'admin_panel', 'reports'];
$users = ['guest' => $guest, 'user' => $user, 'admin' => $admin];

foreach ($users as $userType => $userObj) {
    echo "<h3>{$userType} 用户权限测试</h3>";
    foreach ($pages as $page) {
        $canAccess = $userObj->canAccessPage($page);
        echo "访问 {$page}: " . ($canAccess ? '✓ 允许' : '✗ 拒绝') . "<br>";
    }
}

// 条件访问测试
echo "<h3>条件访问测试</h3>";
$conditions = [
    'is_owner' => true,
    'during_business_hours' => date('H') >= 9 && date('H') <= 17,
    'has_verified_email' => true
];

$canAccess = $user->canAccessWithConditions('profile', $conditions);
echo "用户在有条件下访问个人资料:" . ($canAccess ? '✓ 允许' : '✗ 拒绝') . "<br>";

// 表单验证示例
echo "<h2>表单验证示例</h2>";

$validator = new FormValidator();

// 测试有效数据
echo "<h3>有效数据测试</h3>";
$_POST = [
    'email' => 'user@example.com',
    'password' => 'SecurePass123',
    'confirm' => 'SecurePass123',
    'age' => '25',
    'terms' => 'on'
];

$validator->validateEmail($_POST['email']);
$validator->validatePassword($_POST['password'], $_POST['confirm']);
$validator->validateUserAge($_POST['age']);
$validator->validateTerms($_POST['terms']);

if ($validator->isValid()) {
    echo "<span style='color: green;'>✓ 所有验证通过</span><br>";
} else {
    echo "<span style='color: red;'>✗ 验证失败</span><br>";
}

// 测试无效数据
echo "<h3>无效数据测试</h3>";
$validator2 = new FormValidator();

$_POST = [
    'email' => 'invalid-email',
    'password' => 'weak',
    'confirm' => 'different',
    'age' => 'abc',
    'terms' => ''
];

$validator2->validateEmail($_POST['email']);
$validator2->validatePassword($_POST['password'], $_POST['confirm']);
$validator2->validateUserAge($_POST['age']);
$validator2->validateTerms($_POST['terms']);

if (!$validator2->isValid()) {
    echo "<span style='color: red;'>✗ 发现错误:</span><br>";
    foreach ($validator2->getErrors() as $field => $error) {
        echo "- {$field}: {$error}<br>";
    }
}
?>

字符串运算符

字符串运算符主要用于连接字符串。

字符串连接运算符

<?php
// 字符串连接运算符
$hello = "Hello";
$world = "World";

// 连接运算符(.)
$greeting = $hello . " " . $world . "!";
echo $greeting . "<br>";  // 输出:Hello World!

// 连接赋值运算符(.=)
$text = "PHP ";
$text .= "is ";
$text .= "awesome!";
echo $text . "<br>";  // 输出:PHP is awesome!

// 多种数据类型的连接
$name = "张三";
$age = 25;
$city = "北京";

// 使用连接运算符
$sentence = $name . "今年" . $age . "岁,来自" . $city;
echo $sentence . "<br>";

// 使用双引号的字符串插值(更简洁)
$sentence2 = "$name 今年 $age 岁,来自 $city";
echo $sentence2 . "<br>";

// 复杂数组的连接
$user = [
    'name' => '李四',
    'age' => 30,
    'city' => '上海'
];

$info = "姓名:" . $user['name'] .
        ",年龄:" . $user['age'] .
        ",城市:" . $user['city'];
echo $info . "<br>";

// 使用 Heredoc 处理长文本
$emailBody = <<<EMAIL
尊敬的 {$user['name']}:

感谢您注册我们的服务。

您的信息:
- 年龄:{$user['age']}岁
- 所在城市:{$user['city']}

如有任何问题,请联系我们。

祝好!
客服团队
EMAIL;

echo nl2br($emailBody) . "<br>";
?>

字符串运算符的实际应用

<?php
// HTML生成器类
class HtmlGenerator {
    private $html = '';

    public function addTag($tag, $content = '', $attributes = []) {
        $attrString = '';
        foreach ($attributes as $name => $value) {
            $attrString .= ' ' . $name . '="' . htmlspecialchars($value) . '"';
        }

        if (empty($content)) {
            $this->html .= '<' . $tag . $attrString . '>';
        } else {
            $this->html .= '<' . $tag . $attrString . '>' . $content . '</' . $tag . '>';
        }

        return $this;
    }

    public function addLink($href, $text, $target = '_self') {
        return $this->addTag('a', $text, ['href' => $href, 'target' => $target]);
    }

    public function addImage($src, $alt = '', $width = '', $height = '') {
        $attributes = ['src' => $src];
        if (!empty($alt)) $attributes['alt'] = $alt;
        if (!empty($width)) $attributes['width'] = $width;
        if (!empty($height)) $attributes['height'] = $height;

        return $this->addTag('img', '', $attributes);
    }

    public function addParagraph($text) {
        return $this->addTag('p', $text);
    }

    public function addHeading($text, $level = 1) {
        return $this->addTag('h' . $level, $text);
    }

    public function addListItem($text) {
        return $this->addTag('li', $text);
    }

    public function addList($items, $ordered = false) {
        $tag = $ordered ? 'ol' : 'ul';
        $this->html .= '<' . $tag . '>';

        foreach ($items as $item) {
            $this->addListItem($item);
        }

        $this->html .= '</' . $tag . '>';
        return $this;
    }

    public function addTable($headers, $rows) {
        $this->html .= '<table border="1">';

        // 表头
        $this->html .= '<tr>';
        foreach ($headers as $header) {
            $this->addTag('th', $header);
        }
        $this->html .= '</tr>';

        // 数据行
        foreach ($rows as $row) {
            $this->html .= '<tr>';
            foreach ($row as $cell) {
                $this->addTag('td', $cell);
            }
            $this->html .= '</tr>';
        }

        $this->html .= '</table>';
        return $this;
    }

    public function getHtml() {
        return $this->html;
    }

    public function reset() {
        $this->html = '';
        return $this;
    }
}

// URL构建器类
class UrlBuilder {
    private $baseUrl;
    private $path = '';
    private $params = [];
    private $fragment = '';

    public function __construct($baseUrl = '') {
        $this->baseUrl = rtrim($baseUrl, '/');
    }

    public function setPath($path) {
        $this->path = ltrim($path, '/');
        return $this;
    }

    public function addParam($key, $value) {
        $this->params[$key] = $value;
        return $this;
    }

    public function addParams($params) {
        $this->params = array_merge($this->params, $params);
        return $this;
    }

    public function setFragment($fragment) {
        $this->fragment = ltrim($fragment, '#');
        return $this;
    }

    public function build() {
        $url = $this->baseUrl;

        if (!empty($this->path)) {
            $url .= '/' . $this->path;
        }

        if (!empty($this->params)) {
            $queryParts = [];
            foreach ($this->params as $key => $value) {
                $queryParts[] = urlencode($key) . '=' . urlencode($value);
            }
            $url .= '?' . implode('&', $queryParts);
        }

        if (!empty($this->fragment)) {
            $url .= '#' . $this->fragment;
        }

        return $url;
    }
}

// 日志生成器类
class Logger {
    private $logs = [];

    public function log($level, $message, $context = []) {
        $timestamp = date('Y-m-d H:i:s');
        $contextString = empty($context) ? '' : ' | ' . json_encode($context);
        $logEntry = "[{$timestamp}] {$level}: {$message}{$contextString}";

        $this->logs[] = $logEntry;

        // 同时输出到屏幕
        echo $logEntry . '<br>';

        return $this;
    }

    public function info($message, $context = []) {
        return $this->log('INFO', $message, $context);
    }

    public function warning($message, $context = []) {
        return $this->log('WARNING', $message, $context);
    }

    public function error($message, $context = []) {
        return $this->log('ERROR', $message, $context);
    }

    public function debug($message, $context = []) {
        return $this->log('DEBUG', $message, $context);
    }

    public function getLogs() {
        return $this->logs;
    }

    public function clear() {
        $this->logs = [];
        return $this;
    }

    public function saveToFile($filename) {
        $content = implode("\n", $this->logs);
        return file_put_contents($filename, $content) !== false;
    }
}

// 使用示例
echo "<h2>HTML生成器示例</h2>";

$html = new HtmlGenerator();

$html->addHeading('用户信息', 2)
     ->addParagraph('这是一个HTML生成器的演示。')
     ->addLink('https://www.example.com', '点击访问示例网站')
     ->addHeading('用户列表', 3)
     ->addList(['张三', '李四', '王五'], false)
     ->addHeading('用户详情表', 3)
     ->addTable(
         ['姓名', '年龄', '城市'],
         [
             ['张三', '25', '北京'],
             ['李四', '30', '上海'],
             ['王五', '28', '广州']
         ]
     );

echo $html->getHtml();

echo "<h2>URL构建器示例</h2>";

$urlBuilder = new UrlBuilder('https://api.example.com');
$url1 = $urlBuilder->setPath('users')
                   ->addParam('page', 1)
                   ->addParam('limit', 10)
                   ->addParam('sort', 'name')
                   ->build();

$url2 = (new UrlBuilder('https://www.example.com'))
       ->setPath('search')
       ->addParam('q', 'PHP教程')
       ->addParam('lang', 'zh')
       ->setFragment('results')
       ->build();

echo "API URL: " . $url1 . "<br>";
echo "搜索URL: " . $url2 . "<br>";

echo "<h2>日志生成器示例</h2>";

$logger = new Logger();

$logger->info('用户登录', ['user_id' => 123, 'ip' => '192.168.1.1'])
       ->debug('开始处理数据', ['count' => 100])
       ->warning('内存使用率较高', ['usage' => '85%'])
       ->error('数据库连接失败', ['error_code' => 500])
       ->info('操作完成', ['duration' => '2.5s']);

echo "<h3>日志汇总:</h3>";
foreach ($logger->getLogs() as $log) {
    echo htmlspecialchars($log) . "<br>";
}
?>

数组运算符

数组运算符用于比较和组合数组。

数组运算符类型

<?php
// 数组合并运算符(+)
$array1 = ['a' => 'apple', 'b' => 'banana'];
$array2 = ['b' => 'blueberry', 'c' => 'cherry'];

// + 运算符:右边的数组不会覆盖左边数组中已存在的键
$merged = $array1 + $array2;
print_r($merged);
// 输出:Array ( [a] => apple [b] => banana [c] => cherry )

// array_merge() 函数:右边的数组会覆盖左边数组中已存在的键
$merged2 = array_merge($array1, $array2);
print_r($merged2);
// 输出:Array ( [a] => apple [b] => blueberry [c] => cherry )

// 数组相等比较(==)
$arr1 = [1, 2, 3];
$arr2 = [1, 2, 3];
$arr3 = [1, 3, 2];
$arr4 = ['0' => 1, '1' => 2, '2' => 3];  // 字符串键的数值索引

var_dump($arr1 == $arr2);  // bool(true) - 键值对完全相同
var_dump($arr1 == $arr3);  // bool(false) - 顺序不同
var_dump($arr1 == $arr4);  // bool(true) - PHP自动类型转换

// 数组全等比较(===)
var_dump($arr1 === $arr2);  // bool(true) - 键值对和顺序都相同
var_dump($arr1 === $arr3);  // bool(false) - 顺序不同
var_dump($arr1 === $arr4);  // bool(false) - 键类型不同

// 数组不等比较(!=, <>)
var_dump($arr1 != $arr3);   // bool(true)
var_dump($arr1 <> $arr3);   // bool(true)

// 数组不全等比较(!==)
var_dump($arr1 !== $arr3);  // bool(true)
var_dump($arr1 !== $arr4);  // bool(true)

// 联合数组运算符示例
$config1 = [
    'database' => [
        'host' => 'localhost',
        'port' => 3306
    ],
    'debug' => false
];

$config2 = [
    'database' => [
        'username' => 'root',
        'password' => 'secret'
    ],
    'debug' => true,
    'cache' => [
        'enabled' => true
    ]
];

// 使用 + 运算符合并配置
$mergedConfig = $config1 + $config2;
echo "使用 + 合并配置:<br>";
print_r($mergedConfig);
// database.host, database.port, debug(false) 会被保留

// 使用 array_merge() 合并配置
$deepMerged = array_merge_recursive($config1, $config2);
echo "使用 array_merge_recursive 合并配置:<br>";
print_r($deepMerged);
// 相同键的值会被递归合并
?>

数组运算符的实际应用

<?php
// 配置管理器类
class ConfigManager {
    private $config = [];
    private $defaults = [
        'database' => [
            'host' => 'localhost',
            'port' => 3306,
            'charset' => 'utf8mb4'
        ],
        'app' => [
            'name' => 'MyApp',
            'debug' => false,
            'timezone' => 'UTC'
        ],
        'cache' => [
            'enabled' => false,
            'ttl' => 3600
        ]
    ];

    public function __construct($userConfig = []) {
        // 使用数组运算符合并配置
        $this->config = $this->mergeConfig($this->defaults, $userConfig);
    }

    private function mergeConfig($default, $user) {
        $merged = $default;

        foreach ($user as $key => $value) {
            if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
                $merged[$key] = $this->mergeConfig($merged[$key], $value);
            } else {
                $merged[$key] = $value;
            }
        }

        return $merged;
    }

    public function get($key, $default = null) {
        $keys = explode('.', $key);
        $value = $this->config;

        foreach ($keys as $k) {
            if (!is_array($value) || !array_key_exists($k, $value)) {
                return $default;
            }
            $value = $value[$k];
        }

        return $value;
    }

    public function set($key, $value) {
        $keys = explode('.', $key);
        $config = &$this->config;

        foreach ($keys as $k) {
            if (!is_array($config)) {
                $config = [];
            }
            if (!array_key_exists($k, $config)) {
                $config[$k] = [];
            }
            $config = &$config[$k];
        }

        $config = $value;
    }

    public function getAll() {
        return $this->config;
    }
}

// 购物车比较器类
class ShoppingCartComparer {
    public function compareCarts($cart1, $cart2) {
        $comparison = [
            'identical' => $cart1 === $cart2,
            'equal' => $cart1 == $cart2,
            'items_in_both' => [],
            'items_only_in_cart1' => [],
            'items_only_in_cart2' => [],
            'price_differences' => []
        ];

        // 找出两个购物车中的所有商品
        $allItems = array_merge(array_keys($cart1), array_keys($cart2));
        $allItems = array_unique($allItems);

        foreach ($allItems as $item) {
            $inCart1 = array_key_exists($item, $cart1);
            $inCart2 = array_key_exists($item, $cart2);

            if ($inCart1 && $inCart2) {
                $comparison['items_in_both'][] = $item;

                // 比较价格
                if ($cart1[$item] !== $cart2[$item]) {
                    $comparison['price_differences'][$item] = [
                        'cart1' => $cart1[$item],
                        'cart2' => $cart2[$item],
                        'difference' => $cart2[$item] - $cart1[$item]
                    ];
                }
            } elseif ($inCart1) {
                $comparison['items_only_in_cart1'][] = $item;
            } else {
                $comparison['items_only_in_cart2'][] = $item;
            }
        }

        return $comparison;
    }

    public function formatComparison($comparison) {
        $output = '';

        if ($comparison['identical']) {
            $output .= "两个购物车完全相同<br>";
        } elseif ($comparison['equal']) {
            $output .= "两个购物车内容相同,但顺序可能不同<br>";
        } else {
            $output .= "两个购物车不同<br>";
        }

        if (!empty($comparison['items_in_both'])) {
            $output .= "两个购物车都有的商品:" . implode(', ', $comparison['items_in_both']) . "<br>";
        }

        if (!empty($comparison['items_only_in_cart1'])) {
            $output .= "只在购物车1中的商品:" . implode(', ', $comparison['items_only_in_cart1']) . "<br>";
        }

        if (!empty($comparison['items_only_in_cart2'])) {
            $output .= "只在购物车2中的商品:" . implode(', ', $comparison['items_only_in_cart2']) . "<br>";
        }

        if (!empty($comparison['price_differences'])) {
            $output .= "价格差异:<br>";
            foreach ($comparison['price_differences'] as $item => $diff) {
                $output .= "- {$item}: 购物车1 ¥{$diff['cart1']}, 购物车2 ¥{$diff['cart2']} (差异: ¥{$diff['difference']})<br>";
            }
        }

        return $output;
    }
}

// 权限集合操作类
class PermissionSet {
    private $permissions;

    public function __construct($permissions = []) {
        $this->permissions = array_unique($permissions);
    }

    public function add($permission) {
        $this->permissions[] = $permission;
        $this->permissions = array_unique($this->permissions);
        return $this;
    }

    public function remove($permission) {
        $key = array_search($permission, $this->permissions);
        if ($key !== false) {
            unset($this->permissions[$key]);
        }
        return $this;
    }

    public function has($permission) {
        return in_array($permission, $this->permissions);
    }

    public function hasAny($permissions) {
        foreach ($permissions as $permission) {
            if ($this->has($permission)) {
                return true;
            }
        }
        return false;
    }

    public function hasAll($permissions) {
        foreach ($permissions as $permission) {
            if (!$this->has($permission)) {
                return false;
            }
        }
        return true;
    }

    public function union(PermissionSet $other) {
        return new PermissionSet(array_merge($this->permissions, $other->permissions));
    }

    public function intersection(PermissionSet $other) {
        return new PermissionSet(array_intersect($this->permissions, $other->permissions));
    }

    public function difference(PermissionSet $other) {
        return new PermissionSet(array_diff($this->permissions, $other->permissions));
    }

    public function equals(PermissionSet $other) {
        $sorted1 = $this->permissions;
        $sorted2 = $other->permissions;
        sort($sorted1);
        sort($sorted2);
        return $sorted1 === $sorted2;
    }

    public function getAll() {
        sort($this->permissions);
        return $this->permissions;
    }
}

// 使用示例
echo "<h2>配置管理示例</h2>";

$userConfig = [
    'database' => [
        'host' => 'example.com',
        'username' => 'myuser',
        'password' => 'mypass'
    ],
    'app' => [
        'debug' => true
    ],
    'email' => [
        'from' => 'noreply@example.com'
    ]
];

$configManager = new ConfigManager($userConfig);
echo "数据库主机:" . $configManager->get('database.host') . "<br>";
echo "应用名称:" . $configManager->get('app.name') . "<br>";
echo "调试模式:" . ($configManager->get('app.debug') ? '开启' : '关闭') . "<br>";
echo "邮箱发送者:" . $configManager->get('email.from', '默认邮箱') . "<br>";

echo "<h2>购物车比较示例</h2>";

$cart1 = [
    '苹果' => 5.50,
    '香蕉' => 3.20,
    '橙子' => 8.00
];

$cart2 = [
    '橙子' => 8.00,
    '苹果' => 5.50,
    '葡萄' => 12.00
];

$cart3 = [
    '苹果' => 6.00,  // 价格不同
    '香蕉' => 3.20,
    '橙子' => 8.00
];

$comparer = new ShoppingCartComparer();

echo "<h4>购物车1 vs 购物车2:</h4>";
$comparison1_2 = $comparer->compareCarts($cart1, $cart2);
echo $comparer->formatComparison($comparison1_2);

echo "<h4>购物车1 vs 购物车3:</h4>";
$comparison1_3 = $comparer->compareCarts($cart1, $cart3);
echo $comparer->formatComparison($comparison1_3);

echo "<h2>权限集合操作示例</h2>";

// 创建不同的权限集合
$basicPerms = new PermissionSet(['read', 'comment']);
$adminPerms = new PermissionSet(['read', 'write', 'delete', 'comment']);
$editorPerms = new PermissionSet(['read', 'write', 'edit']);

echo "<h4>基础权限:</h4>";
echo implode(', ', $basicPerms->getAll()) . "<br>";

echo "<h4>管理员权限:</h4>";
echo implode(', ', $adminPerms->getAll()) . "<br>";

// 权限检查
echo "<h4>权限检查:</h4>";
echo "基础权限包含 'read':" . ($basicPerms->has('read') ? '是' : '否') . "<br>";
echo "基础权限包含 'write':" . ($basicPerms->has('write') ? '是' : '否') . "<br>";

// 权限集合操作
$union = $basicPerms->union($editorPerms);
echo "<h4>基础权限 ∪ 编辑权限:</h4>";
echo implode(', ', $union->getAll()) . "<br>";

$intersection = $adminPerms->intersection($editorPerms);
echo "<h4>管理员权限 ∩ 编辑权限:</h4>";
echo implode(', ', $intersection->getAll()) . "<br>";

$difference = $adminPerms->difference($basicPerms);
echo "<h4>管理员权限 - 基础权限:</h4>";
echo implode(', ', $difference->getAll()) . "<br>";

// 复杂权限检查
$multiPerms = new PermissionSet(['read', 'write', 'delete', 'admin', 'user']);
echo "<h4>复杂权限检查:</h4>";
echo "包含任意权限 [" . implode(', ', ['write', 'edit']) . "]:" .
     ($multiPerms->hasAny(['write', 'edit']) ? '是' : '否') . "<br>";
echo "包含所有权限 [" . implode(', ', ['read', 'write', 'admin']) . "]:" .
     ($multiPerms->hasAll(['read', 'write', 'admin']) ? '是' : '否') . "<br>";
?>

位运算符

位运算符直接对整数的二进制位进行操作。

基本位运算符

<?php
$a = 5;  // 二进制:0101
$b = 3;  // 二进制:0011

echo "a = {$a} (二进制: " . decbin($a) . ")<br>";
echo "b = {$b} (二进制: " . decbin($b) . ")<br>";

// 位与(&)
$result = $a & $b;  // 0101 & 0011 = 0001 (1)
echo "a & b = {$result} (二进制: " . decbin($result) . ")<br>";

// 位或(|)
$result = $a | $b;  // 0101 | 0011 = 0111 (7)
echo "a | b = {$result} (二进制: " . decbin($result) . ")<br>";

// 位异或(^)
$result = $a ^ $b;  // 0101 ^ 0011 = 0110 (6)
echo "a ^ b = {$result} (二进制: " . decbin($result) . ")<br>";

// 位取反(~)
$result = ~$a;  // ~0101 = ...1010 (在二进制补码中表示-6)
echo "~a = {$result}<br>";

// 左移(<<)
$result = $a << 1;  // 0101 << 1 = 1010 (10)
echo "a << 1 = {$result} (二进制: " . decbin($result) . ")<br>";

// 右移(>>)
$result = $a >> 1;  // 0101 >> 1 = 0010 (2)
echo "a >> 1 = {$result} (二进制: " . decbin($result) . ")<br>";

// 复杂位运算示例
$flags = 0;
$READ_PERMISSION = 1;    // 0001
$WRITE_PERMISSION = 2;   // 0010
$EXECUTE_PERMISSION = 4; // 0100

$flags = $flags | $READ_PERMISSION;    // 添加读权限
$flags = $flags | $WRITE_PERMISSION;   // 添加写权限

echo "权限标志:{$flags} (二进制: " . decbin($flags) . ")<br>";

// 检查权限
$hasRead = ($flags & $READ_PERMISSION) != 0;
$hasWrite = ($flags & $WRITE_PERMISSION) != 0;
$hasExecute = ($flags & $EXECUTE_PERMISSION) != 0;

echo "有读权限:" . ($hasRead ? '是' : '否') . "<br>";
echo "有写权限:" . ($hasWrite ? '是' : '否') . "<br>";
echo "有执行权限:" . ($hasExecute ? '是' : '否') . "<br>";

// 移除权限
$flags = $flags & ~$WRITE_PERMISSION;
echo "移除写权限后的标志:{$flags} (二进制: " . decbin($flags) . ")<br>";

// 快速乘除2的幂
$number = 10;
$doubled = $number << 1;    // 乘以2
$halved = $number >> 1;      // 除以2
$quadrupled = $number << 2;  // 乘以4

echo "原数:{$number}<br>";
echo "乘以2:{$doubled}<br>";
echo "除以2:{$halved}<br>";
echo "乘以4:{$quadrupled}<br>";
?>

其他运算符

三元运算符

<?php
// 基本三元运算符
$age = 20;
$message = ($age >= 18) ? "成年人" : "未成年人";
echo $message . "<br>";

// 嵌套三元运算符(不推荐,可读性差)
$score = 85;
$grade = ($score >= 90) ? "A" : (($score >= 80) ? "B" : "C");
echo "成绩等级:{$grade}<br>";

// PHP 5.3+ 简化的三元运算符
$username = $_GET['username'] ?: 'Guest';
echo "用户名:{$username}<br>";

// PHP 7.0+ null 合并运算符
$name = $_GET['name'] ?? $_POST['name'] ?? '匿名用户';
echo "姓名:{$name}<br>";

// 实际应用示例
function getPrice($product, $quantity = 1) {
    $basePrice = [
        'apple' => 5,
        'banana' => 3,
        'orange' => 8
    ];

    $price = $basePrice[$product] ?? 0;
    $total = $price * $quantity;

    return [
        'unit_price' => $price,
        'quantity' => $quantity,
        'total' => $total,
        'discount' => $quantity >= 10 ? $total * 0.1 : 0,
        'final_total' => $quantity >= 10 ? $total * 0.9 : $total
    ];
}

$order = getPrice('apple', 12);
echo "订单详情:<br>";
echo "- 单价:¥{$order['unit_price']}<br>";
echo "- 数量:{$order['quantity']}<br>";
echo "- 小计:¥{$order['total']}<br>";
echo "- 折扣:¥{$order['discount']}<br>";
echo "- 总计:¥{$order['final_total']}<br>";
?>

错误控制运算符

<?php
// 错误控制运算符 @
$file = @file_get_contents('nonexistent_file.txt');

if ($file === false) {
    echo "文件读取失败,但没有显示警告信息<br>";
}

// 不使用 @ 的对比
$file2 = file_get_contents('another_nonexistent_file.txt');
// 这会显示一个警告信息

// 数据库连接示例
$connection = @mysqli_connect('invalid_host', 'user', 'pass', 'db');

if (!$connection) {
    echo "数据库连接失败,已静默处理错误<br>";
}

// 注意:过度使用错误控制运算符不是好习惯
// 应该使用适当的错误处理机制
function safeDivide($a, $b) {
    if ($b == 0) {
        return false; // 或者抛出异常
    }
    return $a / $b;
}

$result = safeDivide(10, 0);
if ($result === false) {
    echo "除零错误已安全处理<br>";
}
?>

执行运算符

<?php
// 执行运算符 `` (反引号)
$output = `dir`;  // Windows
// $output = `ls -la`;  // Linux/Mac

echo "目录内容:<pre>" . htmlspecialchars($output) . "</pre>";

// 等同于使用 shell_exec()
$output2 = shell_exec('dir');
echo "使用 shell_exec() 的结果:<pre>" . htmlspecialchars($output2) . "</pre>";

// 注意:执行运算符可能存在安全风险,要谨慎使用
function executeCommand($command) {
    // 白名单命令列表
    $allowedCommands = ['ls', 'dir', 'whoami'];

    $cmdParts = explode(' ', $command);
    $baseCommand = $cmdParts[0];

    if (in_array($baseCommand, $allowedCommands)) {
        return shell_exec($command);
    } else {
        return "命令不被允许";
    }
}

echo "安全执行:<pre>" . htmlspecialchars(executeCommand('dir')) . "</pre>";
echo "尝试执行危险命令:<pre>" . htmlspecialchars(executeCommand('rm -rf /')) . "</pre>";
?>

类型运算符

<?php
// instanceof 运算符
class User {
    public $name = "用户";
}

class Admin extends User {
    public $role = "管理员";
}

$user = new User();
$admin = new Admin();
$string = "hello";

// 检查对象是否是某个类的实例
var_dump($user instanceof User);    // bool(true)
var_dump($admin instanceof User);   // bool(true)(继承关系)
var_dump($admin instanceof Admin);  // bool(true)
var_dump($user instanceof Admin);   // bool(false)
var_dump($string instanceof User);  // bool(false)(不是对象)

// 实际应用
class Animal {
    public function makeSound() {
        return "某种声音";
    }
}

class Dog extends Animal {
    public function makeSound() {
        return "汪汪";
    }
}

class Cat extends Animal {
    public function makeSound() {
        return "喵喵";
    }
}

function makeAnimalSpeak(Animal $animal) {
    if ($animal instanceof Dog) {
        echo "狗说:" . $animal->makeSound() . "<br>";
    } elseif ($animal instanceof Cat) {
        echo "猫说:" . $animal->makeSound() . "<br>";
    } else {
        echo "动物说:" . $animal->makeSound() . "<br>";
    }
}

$dog = new Dog();
$cat = new Cat();
$genericAnimal = new Animal();

makeAnimalSpeak($dog);
makeAnimalSpeak($cat);
makeAnimalSpeak($genericAnimal);
?>

运算符优先级

PHP运算符有不同的优先级,了解优先级对编写正确的表达式很重要。

运算符优先级表(从高到低)

<?php
// 运算符优先级示例
$a = 10;
$b = 5;
$c = 2;

// 乘除优先于加减
$result1 = $a + $b * $c;      // 等同于 $a + ($b * $c) = 10 + (5 * 2) = 20
$result2 = ($a + $b) * $c;     // 等同于 (10 + 5) * 2 = 30

echo "10 + 5 * 2 = {$result1}<br>";
echo "(10 + 5) * 2 = {$result2}<br>";

// 比较运算符优先于逻辑运算符
$x = true;
$y = false;
$z = true;

$result3 = $x and $y or $z;    // 等同于 ($x and $y) or $z = false or true = true
$result4 = $x && $y || $z;     // 等同于 ($x && $y) || $z = false || true = true

// 使用括号明确优先级
$result5 = ($x and ($y or $z)); // 等同于 true and (false or true) = true and true = true

echo "true and false or true: " . ($result3 ? 'true' : 'false') . "<br>";
echo "true && false || true: " . ($result4 ? 'true' : 'false') . "<br>";
echo "true and (false or true): " . ($result5 ? 'true' : 'false') . "<br>";

// 赋值运算符的优先级
$a = $b = $c = 5;            // 从右到左赋值
echo "a = {$a}, b = {$b}, c = {$c}<br>";

$a = 10 + 5;                // 先计算 10 + 5,然后赋值
echo "a = {$a}<br>";

$a += 5 * 2;               // 等同于 $a = $a + (5 * 2) = 15 + 10 = 25
echo "a += 5 * 2, a = {$a}<br>";

// 三元运算符优先级
$value = 10;
$result = $value > 5 ? "大" : "小";
echo "10 > 5 ? '大' : '小' = {$result}<br>";

// 复杂表达式示例
$a = 10;
$b = 5;
$c = 3;
$d = 2;

// 复杂表达式(不推荐,可读性差)
$complex = $a + $b * $c > 20 && $d == 2 || $a - $b < 10;
echo "复杂表达式结果:" . ($complex ? 'true' : 'false') . "<br>";

// 使用括号提高可读性(推荐)
$readable = (($a + ($b * $c)) > 20) && ($d == 2) || (($a - $b) < 10);
echo "可读版本结果:" . ($readable ? 'true' : 'false') . "<br>";

// 实际应用:复杂的条件判断
function canAccessResource($userRole, $userPermissions, $resource) {
    $resourceRequirements = [
        'admin_panel' => ['role' => 'admin'],
        'user_profile' => ['role' => 'user', 'permission' => 'read_profile'],
        'edit_content' => ['permission' => 'edit'],
        'view_reports' => ['role' => 'admin', 'permission' => 'view_reports']
    ];

    $req = $resourceRequirements[$resource] ?? null;

    if (!$req) {
        return false;
    }

    // 复杂的权限检查逻辑
    $hasRole = isset($req['role']) && $userRole === $req['role'];
    $hasPermission = isset($req['permission']) && in_array($req['permission'], $userPermissions);

    // 使用括号明确逻辑
    $canAccess = (isset($req['role']) && isset($req['permission']))
                 ? ($hasRole && $hasPermission)
                 : ($hasRole || $hasPermission);

    return $canAccess;
}

$role = 'user';
$permissions = ['read_profile', 'edit'];

echo "<h3>权限检查示例</h3>";
echo "访问用户资料:" . (canAccessResource($role, $permissions, 'user_profile') ? '允许' : '拒绝') . "<br>";
echo "访问管理面板:" . (canAccessResource($role, $permissions, 'admin_panel') ? '允许' : '拒绝') . "<br>";
echo "编辑内容:" . (canAccessResource($role, $permissions, 'edit_content') ? '允许' : '拒绝') . "<br>";
?>

实际应用示例

综合运算符应用:表达式计算器

<?php
class ExpressionCalculator {
    private $variables = [];

    public function setVariable($name, $value) {
        $this->variables[$name] = $value;
        return $this;
    }

    public function evaluate($expression) {
        // 替换变量
        foreach ($this->variables as $name => $value) {
            $expression = str_replace('{$' . $name . '}', $value, $expression);
        }

        // 安全的表达式求值
        try {
            // 检查表达式是否只包含安全字符
            if (!preg_match('/^[0-9+\-*\/\(\)\s\.]+$/', $expression)) {
                throw new Exception("表达式包含不安全字符");
            }

            // 使用 eval 计算表达式(注意:在实际应用中应该使用更安全的方法)
            $result = eval("return {$expression};");

            return [
                'success' => true,
                'result' => $result,
                'expression' => $expression
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'expression' => $expression
            ];
        }
    }

    public function formatResult($evaluation) {
        if (!$evaluation['success']) {
            return "<span style='color: red;'>错误:{$evaluation['error']}</span>";
        }

        $result = $evaluation['result'];
        $expression = $evaluation['expression'];

        // 格式化数字输出
        if (is_int($result)) {
            $formattedResult = number_format($result);
        } elseif (is_float($result)) {
            $formattedResult = number_format($result, 4);
            $formattedResult = rtrim(rtrim($formattedResult, '0'), '.');
        } else {
            $formattedResult = $result;
        }

        return "{$expression} = <strong>{$formattedResult}</strong>";
    }
}

// 批量数据处理类
class BatchDataProcessor {
    private $data = [];
    private $operations = [];

    public function addData($label, $value) {
        $this->data[$label] = $value;
        return $this;
    }

    public function addOperation($label, $expression) {
        $this->operations[$label] = $expression;
        return $this;
    }

    public function process() {
        $results = [];
        $calculator = new ExpressionCalculator();

        // 设置变量
        foreach ($this->data as $label => $value) {
            $calculator->setVariable($label, $value);
        }

        // 计算操作
        foreach ($this->operations as $label => $expression) {
            $results[$label] = $calculator->evaluate($expression);
        }

        return $results;
    }

    public function displayResults() {
        $results = $this->process();

        echo "<h3>原始数据</h3>";
        echo "<table border='1'>";
        echo "<tr><th>变量</th><th>值</th></tr>";
        foreach ($this->data as $label => $value) {
            echo "<tr><td>\${$label}</td><td>{$value}</td></tr>";
        }
        echo "</table>";

        echo "<h3>计算结果</h3>";
        echo "<table border='1'>";
        echo "<tr><th>操作</th><th>结果</th></tr>";
        foreach ($results as $label => $result) {
            $calculator = new ExpressionCalculator();
            $formattedResult = $calculator->formatResult($result);
            echo "<tr><td>{$label}</td><td>{$formattedResult}</td></tr>";
        }
        echo "</table>";
    }
}

// 使用示例
echo "<h2>表达式计算器示例</h2>";

$calculator = new ExpressionCalculator();
$calculator->setVariable('x', 10)
           ->setVariable('y', 5)
           ->setVariable('z', 2);

$expressions = [
    '{$x} + {$y}',
    '{$x} * {$y} + {$z}',
    '({$x} + {$y}) * {$z}',
    '{$x} > {$y} ? "大于" : "不大于"',
    '{$x} % {$y}',
    '({$x} + {$y} + {$z}) / 3'
];

echo "<h3>基本表达式计算</h3>";
foreach ($expressions as $expr) {
    $result = $calculator->evaluate($expr);
    echo $calculator->formatResult($result) . "<br>";
}

echo "<h2>批量数据处理示例</h2>";

$processor = new BatchDataProcessor();

// 添加销售数据
$processor->addData('jan_sales', 15000)
         ->addData('feb_sales', 18000)
         ->addData('mar_sales', 22000)
         ->addData('cost_rate', 0.6)
         ->addData('tax_rate', 0.08);

// 添加计算操作
$processor->addOperation('Q1总销售额', '{$jan_sales} + {$feb_sales} + {$mar_sales}')
         ->addOperation('平均月销售额', '({$jan_sales} + {$feb_sales} + {$mar_sales}) / 3')
         ->addOperation('Q1总成本', '({$jan_sales} + {$feb_sales} + {$mar_sales}) * {$cost_rate}')
         ->addOperation('Q1毛利润', '({$jan_sales} + {$feb_sales} + {$mar_sales}) * (1 - {$cost_rate})')
         ->addOperation('增长率', '({$mar_sales} - {$jan_sales}) / {$jan_sales} * 100')
         ->addOperation('税费', '({$jan_sales} + {$feb_sales} + {$mar_sales}) * {$tax_rate}')
         ->addOperation('净利润', '({$jan_sales} + {$feb_sales} + {$mar_sales}) * (1 - {$cost_rate} - {$tax_rate})')
         ->addOperation('利润率', '({$jan_sales} + {$feb_sales} + {$mar_sales}) * (1 - {$cost_rate} - {$tax_rate}) / ({$jan_sales} + {$feb_sales} + {$mar_sales}) * 100');

$processor->displayResults();
?>

常见错误和解决方案

1. 运算符优先级错误

<?php
// ❌ 常见错误:优先级理解错误
$result = 5 + 3 * 2;      // 期望 16,实际 11
// 应该使用:$result = (5 + 3) * 2;

// ❌ 逻辑运算符优先级错误
$loggedIn = true;
$hasPermission = false;
// 下面代码可能不会按预期工作
if ($loggedIn = true && $hasPermission) {  // 赋值运算符优先级很低
    echo "有权限访问";
}

// ✅ 正确的做法
if ($loggedIn === true && $hasPermission) {
    echo "有权限访问";
}

// 或者更清晰的写法
if ($loggedIn && $hasPermission) {
    echo "有权限访问";
}
?>

2. 比较运算符类型混淆

<?php
// ❌ 松散比较的问题
if ("0" == false) {
    echo "这会执行,但可能不是你想要的";
}

if ("123abc" == 123) {
    echo "字符串会被转换为数字";
}

// ✅ 使用严格比较
if ("0" === false) {
    echo "这不会执行";
}

if ("123abc" === 123) {
    echo "这不会执行";
}

// 或者明确类型检查
if (is_string($value) && $value === "123") {
    echo "完全匹配";
}
?>

3. 位运算符误用

<?php
// ❌ 对浮点数使用位运算
$float = 3.14;
// $result = $float & 1;  // 这会先将浮点数转换为整数,可能产生意外结果

// ✅ 对整数使用位运算
$int = 3;
$result = $int & 1;  // 结果:1

// ❌ 负数的右移
$negative = -5;
$result = $negative >> 1;  // 结果在不同系统中可能不同

// ✅ 明确处理负数位运算
function safeRightShift($number, $bits) {
    if ($number < 0) {
        return $number >> $bits;  // 系统相关行为
    }
    return $number >> $bits;
}
?>

练习题

基础练习

  1. 算术运算符练习

    $a = 15;
    $b = 4;
    // 计算:$a + $b, $a - $b, $a * $b, $a / $b, $a % $b, $a ** $b
    
  2. 比较运算符练习

    $x = 10;
    $y = "10";
    $z = 5;
    // 比较:$x == $y, $x === $y, $x > $z, $x != $z, $x !== $y
    
  3. 逻辑运算符练习

    $isLogin = true;
    $hasPermission = false;
    $isAdmin = true;
    // 判断:用户是否可以访问管理面板
    

进阶练习

  1. 三元运算符嵌套

    $score = 85;
    // 使用三元运算符判断成绩等级:
    // 90-100: A, 80-89: B, 70-79: C, 60-69: D, 0-59: F
    
  2. 位运算符权限系统

    // 使用位运算符实现权限系统:
    // 定义权限常量,实现权限的添加、删除、检查
    
  3. 数组运算符应用

    // 实现购物车比较功能:
    // 比较两个购物车的商品和价格差异
    

实践练习

  1. 计算器程序 创建一个支持基本运算的计算器:

    • 加减乘除运算
    • 运算符优先级处理
    • 错误处理
  2. 表达式解析器 实现一个简单的表达式解析器:

    • 支持变量替换
    • 基本的数学运算
    • 条件表达式

总结

PHP运算符是编程的基础工具,掌握它们对于编写高效、可读的代码至关重要:

核心概念:

  1. 运算符分类:算术、赋值、比较、逻辑、字符串、数组、位运算符等
  2. 运算符优先级:了解优先级避免逻辑错误
  3. 类型转换:运算符如何处理不同类型的数据
  4. 短路求值:逻辑运算符的性能优化特性

最佳实践:

  • 使用括号明确优先级,提高代码可读性
  • 使用严格比较(===, !==)避免类型转换问题
  • 合理使用三元运算符,避免过度嵌套
  • 理解短路求值,在条件判断中利用其特性
  • 位运算符用于特定场景,如权限系统、标志位等

实际应用要点:

  • 表达式设计:清晰、简洁、可读
  • 错误处理:安全的运算符使用
  • 性能考虑:选择合适的运算符和表达式
  • 代码维护:避免过于复杂的表达式

运算符是PHP编程的基础构件,熟练掌握各种运算符的使用将帮助你编写更加优雅和高效的代码。

下一步学习:掌握运算符后,让我们继续学习PHP的控制结构,了解如何控制程序的执行流程。