主题
条件语句
条件语句根据「是或否」决定走哪一段代码。比较和逻辑运算算出布尔值,if / switch 负责分支。保存为 if.php 后执行 php if.php:
php
<?php
$score = 75;
if ($score >= 60) {
echo "及格\n";
} else {
echo "不及格\n";
}if、else、elseif
if 后面括号里是条件,为真就执行花括号里的语句:
php
<?php
$hour = 9;
if ($hour < 12) {
echo "上午\n";
}条件为假时若还要做另一件事,加 else:
php
<?php
$loggedIn = false;
if ($loggedIn) {
echo "欢迎回来\n";
} else {
echo "请先登录\n";
}多个互斥条件用 elseif(也可以写成 else if,花括号写法下两者等价):
php
<?php
$score = 88;
if ($score >= 90) {
echo "优秀\n";
} elseif ($score >= 80) {
echo "良好\n";
} elseif ($score >= 60) {
echo "及格\n";
} else {
echo "不及格\n";
}从上往下匹配,命中第一个为真的分支就停,后面不再看。所以把更精确、范围更小的条件写在前面:先写 >= 90,再写 >= 80。
只有一条语句时可以省略花括号,但本指南一律加括号,避免加行时改错范围:
php
<?php
if ($score >= 60) echo "及格\n"; // 能跑,不推荐条件是怎么变成真假的
括号里的表达式会当成布尔值。0、""、"0"、[]、null、false 为假,其余为真。细则见 逻辑运算符。
php
<?php
$count = 0;
if ($count) {
echo "有库存\n";
} else {
echo "没库存\n"; // 0 为假,走这里
}要区分 0 和 null,用严格比较:
php
<?php
$count = 0;
if ($count === null) {
echo "还没赋值\n";
} elseif ($count === 0) {
echo "库存为零\n";
} else {
echo "有库存\n";
}不要写 if ($x = 1),那是赋值,条件几乎总为真,变量还会被改掉。比较用 ===,见 赋值运算符。
嵌套与提前返回
分支里还可以再写 if。层数一多就难读,能拆就拆:
php
<?php
$age = 20;
$hasTicket = true;
if ($age >= 18) {
if ($hasTicket) {
echo "可以入场\n";
} else {
echo "请先买票\n";
}
} else {
echo "未满 18 岁\n";
}用逻辑运算压成一层,通常更清楚:
php
<?php
if ($age < 18) {
echo "未满 18 岁\n";
} elseif (!$hasTicket) {
echo "请先买票\n";
} else {
echo "可以入场\n";
}函数里常用「提前 return」减少嵌套,后面讲函数时会再用到。
冒号语法(模板里常见)
和 HTML 混写时,可用 if: / elseif: / else: / endif;,避免满屏花括号:
php
<?php $score = 75; ?>
<?php if ($score >= 90): ?>
<p>优秀</p>
<?php elseif ($score >= 60): ?>
<p>及格</p>
<?php else: ?>
<p>不及格</p>
<?php endif; ?>这种写法里必须用 elseif,不能拆成 else if。纯 PHP 脚本里用花括号即可。
三元运算 ? :
「二选一然后得到一个值」时,可用三元表达式。完整对照(含 ?:、??)见 三元运算符。
php
<?php
$age = 20;
$label = $age >= 18 ? "成年" : "未成年";
echo $label, "\n";PHP 8 禁止没有括号的嵌套三元。假值兜底用 ?:,缺键 / null 用 ??。
switch
同一个变量和许多具体值比较时,用 switch 比一长串 elseif 更整齐:
php
<?php
$role = "editor";
switch ($role) {
case "admin":
echo "可以管理用户\n";
break;
case "editor":
echo "可以编辑文章\n";
break;
case "guest":
echo "只能浏览\n";
break;
default:
echo "未知角色\n";
}执行过程:
- 算出
switch括号里的值 - 从上到下找第一个匹配的
case - 执行到
break(或switch结束) - 都不匹配就走
default(可省略)
必须写 break
没有 break 会继续往下执行后面的 case,这叫 fall-through:
php
<?php
$grade = "B";
switch ($grade) {
case "A":
echo "优秀\n";
// 忘记 break,会继续跑 B
case "B":
echo "良好\n";
break;
default:
echo "其他\n";
}$grade 为 "A" 时会先输出「优秀」再输出「良好」。多数时候这是 bug。
有意让几个值走同一段逻辑时,可以连续写 case、只在最后 break:
php
<?php
$day = "Sat";
switch ($day) {
case "Sat":
case "Sun":
echo "周末\n";
break;
default:
echo "工作日\n";
}switch 用的是 ==
case 和 switch 的值按宽松比较匹配,不是 ===:
php
<?php
$n = 0;
switch ($n) {
case "0":
echo "匹配了字符串 0\n"; // 会走这里,因为 0 == "0"
break;
case 0:
echo "匹配了整数 0\n";
break;
}要按类型严格匹配,用下面的 match。
switch 适合「一个值对多个常量」;范围判断($score >= 90)仍然用 if / elseif。
match(PHP 8,推荐)
match 是 PHP 8 新增的表达式:严格比较、不会穿透、必须有返回值。
php
<?php
$role = "editor";
$message = match ($role) {
"admin" => "可以管理用户",
"editor" => "可以编辑文章",
"guest" => "只能浏览",
default => "未知角色",
};
echo $message, "\n";和 switch 的关键差别:
switch | match | |
|---|---|---|
| 比较方式 | == | === |
| 是否穿透 | 忘记 break 就会 | 不会 |
| 是语句还是表达式 | 语句 | 表达式,能赋给变量 |
| 没匹配到 | 可省略 default | 没有 default 且无匹配会抛 UnhandledMatchError |
| 多个值 | 连续 case | "a", "b" => ... |
多个值写在同一支:
php
<?php
$day = "Sat";
$kind = match ($day) {
"Sat", "Sun" => "周末",
default => "工作日",
};
echo $kind, "\n";match 的每一支必须是单个表达式,不能直接写多行语句。需要多步操作用 if,或把逻辑放到函数里再在 match 里调用。
条件是范围而不是几个常量时,match 也可以用 true 当主语(进阶写法):
php
<?php
$score = 88;
$level = match (true) {
$score >= 90 => "优秀",
$score >= 80 => "良好",
$score >= 60 => "及格",
default => "不及格",
};
echo $level, "\n";初学先掌握「对一个变量匹配几个值」;这种 match (true) 能看懂即可,写复杂范围时用 if 往往更直观。
该用哪一种
| 场景 | 选用 |
|---|---|
| 一个条件、做或不做 | if |
| 二选一 | if / else,或简单时用 三元运算符 |
| 多个范围(分数段、年龄段) | if / elseif |
| 一个变量对几个常量(角色、状态码) | 优先 match,或 switch |
| HTML 模板里插一段 | if: ... endif; |
本指南新代码优先:范围用 if,离散值用 match。读旧项目时你会大量遇到 switch,所以两种都要会。
书写建议
- 花括号不要省,
elseif按「从细到粗」排序 - 条件里用
===/!==,不要在括号里赋值 switch每个逻辑块写break;新代码能用match就用match- 分支超过两三层就拆变量或提前返回
- 输出到 HTML 时仍然要转义,条件再复杂也不例外
练习
- 根据
$hour(0–23)输出「凌晨 / 上午 / 下午 / 晚上」,用if/elseif。 $status为pending、paid、refunded之一,分别用switch和match输出中文状态。- 写一个忘记
break的switch,观察 fall-through;再补上break。 - 用三元运算把
$loggedIn转成字符串已登录/未登录并echo。