写PHP脚本时,循环语句几乎是绕不开的。不管是处理表单数据、遍历数组,还是生成页面内容,for、while、foreach这些结构天天见。但用得多了,问题也容易冒出来。有时候脚本卡死、页面加载不动,很可能就是循环没写对。
无限循环:最典型的“卡死”元凶
最常见的问题就是一不小心写了个无限循环。比如下面这段代码:
for ($i = 0; $i < 10; ) {
echo $i;
}
看起来像是要输出0到9,但条件里的$i++漏掉了。结果$i永远是0,循环停不下来。浏览器打开发呆,服务器CPU直接飙高。遇到这种情况,先别急着重启服务,回代码里查查循环变量有没有更新。
数组遍历时下标越界
用while或for遍历数组时,如果没控制好数组长度,很容易越界。比如:
$arr = [10, 20, 30];
for ($i = 0; $i <= count($arr); $i++) {
echo $arr[$i];
}
这里用了<=,但数组下标最大是2,count返回3,所以最后一次访问$arr[3]会报“Undefined offset”。改成<就安全了。更省心的办法是直接用foreach,自动规避这类问题。
foreach修改原数组的误区
很多人以为在foreach里改$value就能影响原数组,其实不行。比如:
$data = ['a', 'b', 'c'];
foreach ($data as $value) {
$value = strtoupper($value);
}
print_r($data); // 输出还是小写
因为$value是值拷贝。要想真正修改,得用引用方式:
foreach ($data as &$value) {
$value = strtoupper($value);
}
注意加了&符号,这时候改的才是原数据。
循环里嵌SQL查询?小心性能崩盘
有些老代码喜欢在for循环里一条条查数据库:
for ($i = 0; $i < count($ids); $i++) {
$sql = "SELECT name FROM users WHERE id = " . $ids[$i];
// 执行查询
}
10个ID就发10次请求,网络延迟叠加,页面等得让人想关掉。更好的做法是把ID拼成IN语句,一次查完。
跳出循环用错关键词
想跳出当前循环用continue,想彻底退出用break。但有人会搞混。比如过滤数组时:
foreach ($list as $item) {
if ($item['status'] == 'deleted') {
continue; // 跳过当前项,继续下一个
}
process($item);
}
如果这里写成break,后面的数据就全不处理了。差一个字,结果差十万八千里。
循环语句本身不复杂,但细节一错,轻则数据不对,重则服务器瘫痪。写完多想想边界情况,跑一遍测试数据,比上线后再救火强得多。