Увеличение допустимого размера загрузок в PHP: практическое руководство
Настройка размера загружаемых файлов в PHP: основные параметры
Самым эффективным способом изменения лимитов загружаемых файлов является редактирование главного конфигурационного файла php.ini. Этот метод действует глобально для всех скриптов на сервере (или для конкретной версии PHP, если используется несколько интерпретаторов). Для применения изменений требуется перезагрузка веб-сервера (Apache, Nginx) или PHP-FPM.
Основные директивы, отвечающие за размер загрузки:
- upload_max_filesize - максимальный размер одного загружаемого файла (по умолчанию 2M).
- post_max_size - максимальный размер всех данных POST-запроса, включая загружаемые файлы (должен быть больше или равен upload_max_filesize).
- memory_limit - лимит памяти для выполнения скрипта (должен быть достаточным для обработки загруженного файла).
- max_execution_time - максимальное время выполнения скрипта (для больших файлов может потребоваться увеличение).
Пример установки значений в php.ini:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 128M
max_execution_time = 300размер загружаемых файлов php (размер загружаемых файлов php)
Пояснение шагов:
- Открыть файл php.ini (обычно находится в /etc/php/<версия>/apache2/php.ini или /etc/php/<версия>/cli/php.ini, точное расположение зависит от системы).
- Найти указанные директивы и изменить их значения (или добавить, если они закомментированы).
- Сохранить файл и перезапустить веб-сервер: sudo systemctl restart apache2 (или nginx/php-fpm).
- Проверить изменения через phpinfo(): создать файл с <?php phpinfo(); и найти секцию “Resource Limits” или “Core”.
Возможные проблемы и ошибки:
- Значение post_max_size меньше upload_max_filesize. В этом случае загрузка файла будет отклонена с ошибкой “The uploaded file exceeds the MAX_FILE_SIZE directive”. Решение: всегда устанавливать post_max_size больше или равным upload_max_filesize.
- Значение memory_limit слишком мало для обработки файла (например, при работе с изображениями через GD). Ошибка: “Allowed memory size exhausted”. Решение: увеличить memory_limit или оптимизировать обработку.
- Лимит времени выполнения истекает до завершения загрузки. Ошибка: “Maximum execution time exceeded”. Решение: увеличить max_execution_time или использовать фоновую обработку.
- Изменения в php.ini не вступают в силу, если используется пул PHP-FPM с собственным php.ini. Необходимо редактировать именно конфигурацию пула (обычно /etc/php/<версия>/fpm/pool.d/www.conf).
Как увеличить размер загружаемых файлов через .htaccess?
Если доступ к php.ini отсутствует (например, на хостинге), можно изменить параметры через файл .htaccess (если веб-сервер Apache и разрешена директива AllowOverride All). Метод работает для текущей директории и её поддиректорий.
php_value upload_max_filesize 32M
php_value post_max_size 32M
php_value memory_limit 64M
php_value max_execution_time 120
Пояснение:
- Директивы php_value и php_flag позволяют задавать настройки PHP на уровне директории.
- Файл .htaccess должен быть размещён в корневой папке сайта или в папке, где выполняется загрузка.
- После сохранения изменений перезагрузка сервера не требуется, но нужно убедиться, что хостинг разрешает переопределение настроек через .htaccess.
Типичные ошибки:
- HTTP 500 Internal Server Error - если синтаксис .htaccess неверен или директива не разрешена. Проверить с помощью простой записи: php_value upload_max_filesize 10M (без лишних пробелов).
- На серверах Nginx .htaccess не поддерживается, необходимо использовать другие методы.
Как настроить параметры загрузки через ini_set() в коде?
Функция ini_set() позволяет временно изменить настройки PHP на время выполнения одного скрипта. Однако такие директивы, как upload_max_filesize и post_max_size, не могут быть изменены после начала обработки запроса (они относятся к константам PHP_INI_SYSTEM). Зато можно изменить memory_limit и max_execution_time.
<?php
ini_set('memory_limit', '256M');
ini_set('max_execution_time', '600');
// Дальнейший код обработки загрузки
?>
Пояснение: вызов ini_set() в начале скрипта даёт PHP больше памяти и времени для обработки большого файла. Этот метод полезен, когда изменить глобальные настройки невозможно.
Ошибка:
Если попробовать изменить upload_max_filesize через ini_set(), вызов не вызовет ошибки, но значение не изменится (останется предыдущее). Поэтому для этого параметра нужно использовать другие методы (php.ini или .htaccess).
Как задать лимиты через .user.ini при использовании CGI/FPM?
В PHP, работающем через CGI или FPM, поддерживается файл .user.ini, который работает аналогично .htaccess, но специфичен для PHP. Он читается при старте PHP и не требует перезагрузки сервера.
upload_max_filesize = 50M
post_max_size = 50M
max_execution_time = 120
Пояснение: файл .user.ini размещается в корневой директории сайта. Изменения подхватываются автоматически для каждого нового запроса.
Проблемы:
- Файл .user.ini может быть проигнорирован, если на сервере отключена поддержка (обычно включена по умолчанию).
- Параметры из .user.ini имеют приоритет над php.ini, но ниже .htaccess.
Как ограничить размер загрузки на стороне веб-сервера (Nginx)?
На Nginx существует своя директива client_max_body_size, которая ограничивает размер тела запроса. Даже если в PHP установлено большое значение, Nginx может отклонить запрос раньше.
# В контексте http, server или location
location /upload {
client_max_body_size 100M;
proxy_pass http://backend;
}
Пояснение: Значение задаётся в мегабайтах (M), килобайтах (k) или гигабайтах (G). После изменений конфигурации нужно перезагрузить Nginx: sudo nginx -s reload.
Ошибка:
Если client_max_body_size меньше, чем post_max_size в PHP, то Nginx вернёт ошибку 413 (Request Entity Too Large). Решение - синхронизировать эти значения.
Расширенные примеры и результаты
Пример 1. Проверка текущих лимитов через phpinfo() и скрипт
Создать файл info.php:
<?php
phpinfo();
?>
После открытия в браузере найти раздел “Core” (или “Resource Limits”). Результат (фрагмент):
Directive Local Value Master Value upload_max_filesize 2M 2M post_max_size 8M 8M memory_limit 128M 128M max_execution_time 30 30
Пояснение: Видны текущие значения. Чтобы изменить любое, нужно действовать одним из описанных методов.
Пример 2. Использование ini_set() для memory_limit с последующей проверкой
<?php
echo 'Начальный memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
ini_set('memory_limit', '512M');
echo 'После ini_set: ' . ini_get('memory_limit') . PHP_EOL;
// Попытка изменить upload_max_filesize
ini_set('upload_max_filesize', '100M');
echo 'upload_max_filesize после ini_set: ' . ini_get('upload_max_filesize') . PHP_EOL;
?>
Начальный memory_limit: 128M После ini_set: 512M upload_max_filesize после ini_set: 2M
Пояснение: memory_limit изменился, а upload_max_filesize остался прежним, так как относится к PHP_INI_SYSTEM.
Пример 3. Настройка через .htaccess и проверка через заголовки
# Содержимое .htaccess
php_value upload_max_filesize 20M
php_value post_max_size 20M
php_value max_execution_time 60
Результат: При загрузке файла размером 15 МБ ошибок не возникает. Проверить через скрипт:
<?php
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: ' . ini_get('post_max_size') . PHP_EOL;
?>
upload_max_filesize: 20M post_max_size: 20M
Пример 4. Совместная настройка Nginx + PHP-FPM
Конфигурационный файл Nginx (site.conf):
server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location /upload {
client_max_body_size 200M;
proxy_pass http://127.0.0.1:8080;
}
}
Параллельно в php.ini (или .user.ini) установить post_max_size = 200M и upload_max_filesize = 200M. Результат: сервер Nginx пропускает тело запроса до 200 МБ, PHP принимает файлы до 200 МБ.
Пример 5. Использование .user.ini в поддиректории
Структура: /var/www/html/upload/.user.ini
upload_max_filesize = 100M
post_max_size = 100M
max_file_uploads = 20 (необязательно)
Проверка через скрипт в этой папке:
<?php
echo 'Лимиты в папке upload:' . PHP_EOL;
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: ' . ini_get('post_max_size') . PHP_EOL;
echo 'max_file_uploads: ' . ini_get('max_file_uploads') . PHP_EOL;
?>
Лимиты в папке upload: upload_max_filesize: 100M post_max_size: 100M max_file_uploads: 20
При этом в корневой папке лимиты могут быть другими (если не заданы в .user.ini).
Пример 6. Обработка ошибок на стороне PHP и вывод полезного сообщения
<?php
$maxSize = ini_get('upload_max_filesize');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_FILES['file']['error'] === UPLOAD_ERR_INI_SIZE) {
echo "Файл превышает максимальный размер, установленный PHP: $maxSize";
} elseif ($_FILES['file']['error'] === UPLOAD_ERR_FORM_SIZE) {
echo "Файл превышает значение MAX_FILE_SIZE в форме.";
} else {
// обработка успешной загрузки
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
echo "Файл загружен успешно.";
}
}
?>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="2097152" /> <!-- 2 MB -->
<input type="file" name="file" />
<input type="submit" value="Загрузить" />
</form>
Результат: пользователь видит конкретную причину отказа, если файл слишком большой.
Пример 7. Настройка в Apache через httpd.conf (глобально для виртуального хоста)
<VirtualHost *:80>
DocumentRoot "/var/www/site"
ServerName site.local
<Directory "/var/www/site">
AllowOverride All
Options Indexes FollowSymLinks
Require all granted
php_value upload_max_filesize 48M
php_value post_max_size 48M
php_value max_execution_time 180
</Directory>
</VirtualHost>
Результат: для данного виртуального хоста устанавливаются лимиты, перезаписывая значения из php.ini.