本文目录导读:

在 PHP 中,while(1) 或 while(true) 是一个无条件无限循环,如果不加防护,会导致脚本超时崩溃(通常是 30 秒默认限制)或服务器资源占满。
核心防御机制
1 设置执行时间限制
// 设置最大执行时间为 10 秒
set_time_limit(10);
$count = 0;
while(1) {
// 业务逻辑
$count++;
// 检查是否超时
if (connection_aborted()) {
break; // 客户端断开连接时退出
}
// 手工检查时间
if (microtime(true) - $start > 8) {
break; // 运行超过 8 秒退出
}
}
2 最大迭代次数限制
$max_iterations = 100000;
$count = 0;
while(1) {
// 业务逻辑
$count++;
// 达到最大迭代次数退出
if ($count >= $max_iterations) {
break;
}
// 其他退出条件
if (someCondition()) {
break;
}
}
完整防御示例
<?php
// 防御性无限循环
function safeInfiniteLoop() {
// 配置
$start_time = microtime(true);
$max_execution_time = 10; // 秒
$max_iterations = 100000;
$min_sleep = 100000; // 微秒 (0.1秒)
$iteration_count = 0;
while(1) {
$iteration_count++;
// 1. 时间限制检查
if (microtime(true) - $start_time > $max_execution_time) {
error_log("Loop exceeded time limit");
break;
}
// 2. 迭代次数限制
if ($iteration_count > $max_iterations) {
error_log("Loop exceeded iteration limit");
break;
}
// 3. 内存限制检查
if (memory_get_usage(true) > 100 * 1024 * 1024) { // 100MB
error_log("Memory limit exceeded");
break;
}
// 4. 客户端连接检查
if (connection_aborted()) {
error_log("Client disconnected");
break;
}
// 5. 自定义退出条件
if (shouldExit()) {
break;
}
// 6. 防止 CPU 100% - 加少量休眠
// 非必须操作时不要频繁循环
usleep($min_sleep);
// 执行业务逻辑
processData();
// 7. 反馈进度 (可选)
if ($iteration_count % 1000 == 0) {
echo "Processed: $iteration_count\n";
flush();
}
}
}
特定场景防御
1 长轮询/WebSocket
// 使用 PHP-FPM 的长轮询
$timeout = 30; // 30秒超时
$start = time();
while(time() - $start < $timeout) {
$new_data = checkForNewData();
if ($new_data) {
echo json_encode($new_data);
flush();
break;
}
// 每1秒检查一次
sleep(1);
}
2 后台守护进程
// 使用多进程或 Supervisor 管理
while(1) {
// 1. 检查进程是否存在
if (!file_exists('/tmp/daemon.pid')) {
break;
}
// 2. 检查信号
if (pcntl_signal_dispatch()) {
// 处理信号
}
// 3. 工作逻辑
processQueue();
sleep(1);
}
最佳实践建议
- 尽量避免
while(1)- 99% 的场景可以用其他方式实现 - 使用队列系统 - 如 Redis/RabbitMQ 替代无限循环
- 设置多重限制 - 时间、次数、内存、连接状态
- 使用进程管理工具 - Supervisor、systemd 管理长脚本
- 添加心跳检测 - 外部监控脚本检查进程存活
调试技巧
// 调试模式 - 打印循环状态
error_reporting(E_ALL);
ini_set('display_errors', 1);
$debug = true;
$count = 0;
while(1) {
$count++;
if ($debug && $count % 100 == 0) {
echo "Iteration: $count, Memory: " . memory_get_usage(true) . "\n";
}
// ... 业务代码
}
无限循环是最后的选择,优先考虑轮询、队列、事件驱动等模式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播