运算符
什么是运算符?
在编程中,运算符是用于执行特定数学或逻辑操作的符号。PHP提供了丰富的运算符,可以对不同类型的数据进行各种操作。
运算符的基本组成部分:
- 操作数:参与运算的数据(变量、常量或字面值)
- 运算符:执行操作的符号(如
+、-、*、/) - 表达式:运算符和操作数的组合,产生一个值
例如,在表达式 2 + 3 中:
2和3是操作数+是运算符2 + 3是表达式,结果为5
PHP运算符分类
PHP的运算符可以分为以下几大类:
- 算术运算符:执行数学计算
- 赋值运算符:给变量赋值
- 比较运算符:比较两个值
- 逻辑运算符:执行布尔逻辑操作
- 字符串运算符:连接字符串
- 数组运算符:比较和组合数组
- 位运算符:对二进制位进行操作
- 其他运算符:三元运算符、错误控制等
算术运算符
算术运算符用于执行基本的数学运算。
基本算术运算符
<?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;
}
?>
练习题
基础练习
-
算术运算符练习
$a = 15; $b = 4; // 计算:$a + $b, $a - $b, $a * $b, $a / $b, $a % $b, $a ** $b -
比较运算符练习
$x = 10; $y = "10"; $z = 5; // 比较:$x == $y, $x === $y, $x > $z, $x != $z, $x !== $y -
逻辑运算符练习
$isLogin = true; $hasPermission = false; $isAdmin = true; // 判断:用户是否可以访问管理面板
进阶练习
-
三元运算符嵌套
$score = 85; // 使用三元运算符判断成绩等级: // 90-100: A, 80-89: B, 70-79: C, 60-69: D, 0-59: F -
位运算符权限系统
// 使用位运算符实现权限系统: // 定义权限常量,实现权限的添加、删除、检查 -
数组运算符应用
// 实现购物车比较功能: // 比较两个购物车的商品和价格差异
实践练习
-
计算器程序 创建一个支持基本运算的计算器:
- 加减乘除运算
- 运算符优先级处理
- 错误处理
-
表达式解析器 实现一个简单的表达式解析器:
- 支持变量替换
- 基本的数学运算
- 条件表达式
总结
PHP运算符是编程的基础工具,掌握它们对于编写高效、可读的代码至关重要:
核心概念:
- 运算符分类:算术、赋值、比较、逻辑、字符串、数组、位运算符等
- 运算符优先级:了解优先级避免逻辑错误
- 类型转换:运算符如何处理不同类型的数据
- 短路求值:逻辑运算符的性能优化特性
最佳实践:
- 使用括号明确优先级,提高代码可读性
- 使用严格比较(===, !==)避免类型转换问题
- 合理使用三元运算符,避免过度嵌套
- 理解短路求值,在条件判断中利用其特性
- 位运算符用于特定场景,如权限系统、标志位等
实际应用要点:
- 表达式设计:清晰、简洁、可读
- 错误处理:安全的运算符使用
- 性能考虑:选择合适的运算符和表达式
- 代码维护:避免过于复杂的表达式
运算符是PHP编程的基础构件,熟练掌握各种运算符的使用将帮助你编写更加优雅和高效的代码。
下一步学习:掌握运算符后,让我们继续学习PHP的控制结构,了解如何控制程序的执行流程。