本文目录导读:

在 PHP 中,资源限制主要涉及内存、执行时间、文件上传等几个方面,以下是全面的配置和解决方案:
内存限制(Memory Limit)
配置文件方式(php.ini)
; 最大内存限制 memory_limit = 128M ; 单脚本最大内存(推荐生产环境设置) memory_limit = 256M
代码动态设置
// 设置内存限制(必须在脚本开头)
ini_set('memory_limit', '256M');
// 获取当前内存限制
echo ini_get('memory_limit');
// 查看当前使用内存
echo memory_get_usage(); // 字节
echo memory_get_peak_usage(); // 峰值
执行时间限制(Execution Time)
配置文件方式
; 最大执行时间(秒) max_execution_time = 30 ; CLI模式默认无限制 ; 建议CLI设为0 max_execution_time = 0
代码动态设置
// 设置执行时间(秒)
set_time_limit(30);
// 获取当前设置
echo ini_get('max_execution_time');
// 无限执行(用于CLI或某些特殊场景)
set_time_limit(0);
文件上传限制
配置文件方式
; 是否允许上传 file_uploads = On ; 上传临时目录 upload_tmp_dir = "/tmp" ; 最大上传文件大小 upload_max_filesize = 20M ; POST最大大小(需大于上传大小) post_max_size = 25M ; 最大文件上传数量 max_file_uploads = 20
代码检查
// 检查上传错误
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
// 成功处理
} else {
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_INI_SIZE:
echo "超过PHP配置限制";
break;
case UPLOAD_ERR_FORM_SIZE:
echo "超过表单限制";
break;
}
}
其他常见资源限制
脚本输入限制
; POST数据最大大小 post_max_size = 8M ; 请求最大时间(秒) max_input_time = 60 ; 输入变量数量限制 max_input_vars = 1000
输出缓冲
; 输出缓冲大小 output_buffering = 4096 ; 压缩输出 zlib.output_compression = On zlib.output_compression_level = 5
运行时检测与优化
// 内存使用监控
class MemoryMonitor {
private $startMemory;
private $startTime;
public function __construct() {
$this->startMemory = memory_get_usage();
$this->startTime = microtime(true);
}
public function getUsage() {
return [
'memory' => memory_get_usage() - $this->startMemory,
'peak_memory' => memory_get_peak_usage(),
'time' => microtime(true) - $this->startTime
];
}
}
// 使用示例
$monitor = new MemoryMonitor();
// 执行代码...
print_r($monitor->getUsage());
常用操作技巧
释放大变量内存
// 大数组处理完后释放
unset($largeArray);
gc_collect_cycles(); // 强制垃圾回收
// 分批处理大数据
foreach (array_chunk($largeData, 1000) as $chunk) {
processData($chunk);
unset($chunk); // 释放
}
超时处理模式
// 设置超时并捕获
try {
set_time_limit(10);
// 可能超时的代码
$result = processData();
} catch (Exception $e) {
// 超时处理
error_log("Timeout: " . $e->getMessage());
}
// 使用pcntl实现更精确超时(Linux)
if (function_exists('pcntl_alarm')) {
pcntl_signal(SIGALRM, function() {
throw new Exception("Timeout");
});
pcntl_alarm(10); // 10秒后触发
}
常见问题处理
解决内存溢出
// 1. 增加限制
ini_set('memory_limit', '-1'); // -1表示不限制,慎重!
// 2. 优化代码
// - 避免一次性加载大文件
$file = fopen("large.csv", "r");
while (($line = fgetcsv($file)) !== false) {
processRow($line);
}
fclose($file);
// 3. 使用流式处理
$stream = fopen("php://temp", 'r+');
fwrite($stream, $largeData);
rewind($stream);
处理长时间任务
// CLI模式推荐
if (php_sapi_name() === 'cli') {
set_time_limit(0);
ini_set('memory_limit', '1G');
}
// Web模式使用异步/队列
// 推荐使用 Redis 队列 + Worker
最佳实践建议
生产环境推荐配置
; memory_limit memory_limit = 256M ; Time max_execution_time = 60 max_input_time = 120 ; Upload upload_max_filesize = 50M post_max_size = 55M ; 开启错误日志 error_reporting = E_ALL log_errors = On
监控工具
// 使用Composer包检查资源使用
// composer require filp/whoops
// 或自建简单监控
class ResourceAudit {
public static function logUsage() {
$usage = [
'memory' => memory_get_usage(true),
'peak' => memory_get_peak_usage(true),
'time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']
];
error_log(json_encode($usage));
}
}
register_shutdown_function(['ResourceAudit', 'logUsage']);
框架级别的限制
Laravel 示例
// config/app.php
'middleware' => [
\App\Http\Middleware\SetMemoryLimit::class,
]
// 自定义中间件
class SetMemoryLimit {
public function handle($request, Closure $next) {
ini_set('memory_limit', '512M');
return $next($request);
}
}
注意事项
- 不要盲目调大限制:应根据实际需求设置,过大可能耗尽服务器资源
- 区分CLI和Web:CLI模式可以放宽限制,Web模式需要保守
- 使用队列处理大任务:对耗时操作使用消息队列
- 监控告警:建立资源使用监控和告警机制
- 代码优化优先:遇到资源问题,先优化代码而不是调大限制
资源限制的目的是防止程序失控,合理配置 + 代码优化才是最佳实践。