本文目录导读:

- set_time_limit() 函数
- ini_set() 方法
- 配置文件修改
- .htaccess 文件配置(Apache环境)
- 命令行模式(CLI)
- 控制数据库查询超时
- 安全的超时处理模式
- 处理长耗时任务的最佳实践
- 注意事项
- 最快的方法
在PHP中控制脚本超时主要有以下几种方法:
set_time_limit() 函数
最常用的方法,设置脚本最大执行时间(秒)。
// 设置脚本最大执行时间为30秒 set_time_limit(30); // 设置为0表示无限制(需谨慎使用) set_time_limit(0); // 也可以指定起始时间 $start_time = time(); set_time_limit(30); // 从现在开始30秒
ini_set() 方法
修改PHP配置中的执行时间限制。
// 设置最大执行时间为60秒
ini_set('max_execution_time', 60);
// 或者
ini_set('max_execution_time', 0); // 无限制
配置文件修改
修改php.ini文件中的max_execution_time参数。
; 设置最大执行时间为60秒 max_execution_time = 60 ; 注意:CLI模式下默认设置为0(无限制)
.htaccess 文件配置(Apache环境)
# 针对PHP脚本设置超时时间(单位:秒) php_value max_execution_time 300
命令行模式(CLI)
// CLI环境下,默认是没有时间限制的 // 但可以通过以下方式设置: set_time_limit(30); // 在脚本中设置 // 或者在命令行调用时使用 -d 参数 // php -d max_execution_time=30 script.php
控制数据库查询超时
// MySQL查询超时
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_TIMEOUT, 30); // 30秒超时
// mysqli
mysqli_options($conn, MYSQLI_OPT_CONNECT_TIMEOUT, 30);
安全的超时处理模式
<?php
// 安全的超时处理示例
class ScriptTimeout {
private static $startTime;
public static function init() {
self::$startTime = microtime(true);
}
public static function checkTimeout($timeout) {
$executionTime = microtime(true) - self::$startTime;
if ($executionTime >= $timeout) {
throw new Exception("脚本执行超时");
}
}
}
// 使用示例
ScriptTimeout::init();
set_time_limit(60); // 设置总超时时间
try {
// 长循环处理
while($some_condition) {
ScriptTimeout::checkTimeout(55); // 提前5秒退出
// 业务逻辑...
usleep(100000); // 0.1秒
}
} catch (Exception $e) {
echo "处理超时: " . $e->getMessage();
}
处理长耗时任务的最佳实践
<?php
// 异步处理方式
set_time_limit(0); // 取消时间限制
// 使用pcntl_fork创建子进程
$pid = pcntl_fork();
if ($pid == -1) {
die('无法创建子进程');
} else if ($pid) {
// 父进程
pcntl_waitpid($pid, $status);
echo "任务完成";
} else {
// 子进程
// 执行长时间任务
sleep(120);
exit(0);
}
注意事项
-
版本差异:PHP 5.3+中,
max_execution_time只限制CPU执行时间,不包含sleep()等阻塞时间 -
CLI和Web模式差异:CLI默认无超时限制,Web模式默认受
max_execution_time限制 -
资源释放:建议在超时脚本中正确释放数据库连接、文件句柄等资源
// 资源释放示例
set_time_limit(10);
// 注册超时处理
register_shutdown_function(function() {
if (connection_status() != CONNECTION_NORMAL) {
// 脚本被中断,清理资源
if (isset($GLOBALS['db'])) {
$GLOBALS['db']->close();
}
}
});
最快的方法
<?php // 最简单直接的示例 set_time_limit(30); // 设置30秒超时 // 你的业务代码 // ...
选择合适的方法取决于你的具体需求场景:
- 单个脚本:使用
set_time_limit() - 权限受限环境:使用
.htaccess配置 - 长期运行的任务:使用
set_time_limit(0)配合适当的错误处理