Загрузка файлов — ключевой функционал любого сайта на WordPress, особенно если вы работаете с медиа или пользовательским контентом. Но иногда возникают ошибки при загрузке, особенно если на сервере установлены ограничения по размеру файлов, времени выполнения скриптов или памяти. В этой статье мы подробно разберём, как выявить и устранить эти ограничения, чтобы загрузка файлов в WordPress работала без сбоев.
Проверка и изменение настроек PHP для загрузки файлов
Основные параметры PHP, влияющие на загрузку файлов:
upload_max_filesize— максимальный размер загружаемого файла;post_max_size— максимальный размер данных, отправляемых методом POST;max_execution_time— максимальное время выполнения скрипта;memory_limit— максимальный объём памяти, выделяемый PHP.
Если эти значения слишком малы, загрузка больших файлов будет прерываться с ошибкой. Чтобы проверить текущие настройки, создайте в корне сайта файл phpinfo.php с содержимым:
<?php
phpinfo();
?>
Откройте его в браузере: https://ваш_домен/phpinfo.php. Найдите параметры upload_max_filesize и post_max_size. Обычно, чтобы загружать файлы до 64 МБ, эти значения нужно установить как минимум 64M.
Изменить настройки можно в php.ini или в .htaccess (если сервер Apache) добавив:
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value memory_limit 256M
После изменения настроек перезапустите сервер или обратитесь к хостеру.
Использование фильтров WordPress для обхода ограничений PHP
В некоторых случаях доступ к php.ini ограничен. Тогда можно попытаться увеличить лимиты программно, добавив в functions.php вашей темы или в отдельный плагин следующий код:
function wpupload_increase_upload_limits() {
@ini_set('upload_max_size' , '64M');
@ini_set('post_max_size', '64M');
@ini_set('max_execution_time', '300');
@ini_set('memory_limit', '256M');
}
add_action('init', 'wpupload_increase_upload_limits');
Этот способ не всегда срабатывает, но стоит попробовать, если нет доступа к настройкам сервера.
Обработка ошибок загрузки в WordPress и пользовательские сообщения
Для качественного UX важно, чтобы пользователь получил понятное сообщение, если загрузка не удалась. WordPress генерирует ошибки при загрузке файлов, но можно их отлавливать и показывать свои сообщения.
Пример функции, которая перехватывает ошибку загрузки и выводит своё сообщение:
function wpupload_custom_upload_error($errors, $file, $file_info) {
if (!empty($errors)) {
foreach ($errors as $key => $error) {
if (strpos($error, 'exceeds the maximum upload size') !== false) {
$errors[$key] = 'Файл слишком большой. Максимальный размер: 64МБ.';
}
}
}
return $errors;
}
add_filter('wp_handle_upload_prefilter', function($file) {
$max_size = 64 * 1024 * 1024; // 64MB
if ($file['size'] > $max_size) {
$file['error'] = 'Файл слишком большой. Максимальный размер: 64МБ.';
}
return $file;
});
Таким образом вы можете управлять сообщениями и улучшать опыт пользователей.
Примеры плагинов для расширенного управления загрузкой файлов
Если вы хотите получить более гибкий контроль над загрузкой файлов, стоит обратить внимание на плагины:
- WP Upload Restriction — позволяет ограничивать типы и размеры загружаемых файлов.
- Disable Real MIME Check — помогает решить проблемы с MIME-типами, которые иногда блокируют загрузку.
- Clearfy Pro — улучшает производительность и безопасность, включая оптимизацию работы с загрузками.
Вы можете найти эти и другие полезные плагины на WPSHOP.ru.
Обход ограничений сервера с помощью chunked upload (пошаговая загрузка)
Если сервер накладывает жесткие ограничения на размер файла, можно реализовать загрузку по частям (chunked upload). WordPress по умолчанию этого не умеет, но вы можете добавить такую логику с помощью JavaScript и PHP.
Основная идея — разбить файл на небольшие части и загружать их по отдельности, а сервер собирает обратно.
Пример простой реализации на стороне PHP:
function wpupload_handle_chunked_upload() {
$targetDir = wp_upload_dir()['path'] . '/temp_chunks/';
if (!file_exists($targetDir)) {
mkdir($targetDir, 0755, true);
}
$chunkIndex = isset($_POST['chunkIndex']) ? intval($_POST['chunkIndex']) : 0;
$totalChunks = isset($_POST['totalChunks']) ? intval($_POST['totalChunks']) : 1;
$fileName = sanitize_file_name($_POST['fileName']);
$chunkData = file_get_contents($_FILES['file']['tmp_name']);
file_put_contents($targetDir . $fileName . '.part' . $chunkIndex, $chunkData);
if ($chunkIndex === $totalChunks - 1) {
$finalPath = wp_upload_dir()['path'] . '/' . $fileName;
$out = fopen($finalPath, 'wb');
for ($i = 0; $i < $totalChunks; $i++) {
$chunk = file_get_contents($targetDir . $fileName . '.part' . $i);
fwrite($out, $chunk);
unlink($targetDir . $fileName . '.part' . $i);
}
fclose($out);
rmdir($targetDir);
// Здесь можно добавить регистрацию файла в медиабиблиотеке
}
wp_send_json_success();
}
add_action('wp_ajax_wpupload_chunked_upload', 'wpupload_handle_chunked_upload');
add_action('wp_ajax_nopriv_wpupload_chunked_upload', 'wpupload_handle_chunked_upload');
С клиентской стороны загрузка реализуется через JavaScript с разделением файла на части и отправкой их AJAX запросами. Это сложнее, но даёт возможность загружать файлы значительно больше лимитов сервера.