WordPress. Загрузка файлов. Часть 1 из 3
В WordPress есть множество функций, предназначенных для загрузки файлов. Сразу разобраться в них трудно — названия похожие и функционал часто дублируется. Рассмотрим последовательно все функции и попробуем загрузить файлы на сервер сначала в панели управления, а потом и в публичной части сайта. Для этого создадим плагин и будем его постепенно изменять, чтобы рассмотреть все возможности WordPress по загрузке файлов.
Загрузка файлов в панели управления
Простая загрузка одного файла
На первом этапе плагин просто загружает файл в соответствующую поддиректорию (year/month
) директории /wp-content/uploads
. Запись в таблицу базы данных wp_posts
при этом не добавляется, т.е. этот файл не является вложением и недоступен для просмотра в библиотеке медиафайлов. Всю работу по загрузке файла выполняет функция wp_handle_upload()
, которая является оберткой для нативной php-функции move_uploaded_file()
.
<?php /* * Plugin name: Загрузка файлов * Description: Пример загрузки файлов в панели управления */ /* * Добавляем страницу плагина в панели управления */ add_action('admin_menu', function () { add_menu_page( // содержимое тега title этой страницы 'Загрузка файлов', // название пункта меню для этой страницы 'Загрузка файлов', // права доступа, чтобы был показан этот пункт меню 'upload_files', // уникальный идентификатор меню (страницы) 'tokmakov_upload_page', // функция выводит содержимое этой страницы function () { ?> <div class="wrap"> <h1>Загрузка файлов</h1> <p> Плагин позволяет загружать файлы в директорию <code>/wp-content/uploads</code>. Обратите внимание, что загружаются только файлы, это не вложения (attachments). Записи в таблицу <code>wp_posts</code> не добавляются, поэтому в библиотеке медиафайлов эти файлы будут не видны. </p> <?php if (isset($_SESSION['tokmakov_upload_file'])): ?> <p><?= $_SESSION['tokmakov_upload_file']; ?></p> <?php unset($_SESSION['tokmakov_upload_file']); ?> <?php endif; ?> <?php $action = admin_url('admin-post.php'); $redirect = $_SERVER['REQUEST_URI']; ?> <form action="<?= $action; ?>" method="post" enctype="multipart/form-data"> <?php wp_nonce_field('tokmakov_upload_file'); ?> <input type="hidden" name="action" value="tokmakov_upload_file" /> <input type="hidden" name="redirect" value="<?= $redirect ?>" /> <input type="file" name="tokmakov_upload_file" required /> <input type="submit" value="Загрузить файл" /> </form> </div> <?php }, // иконка для страницы настроек плагина 'dashicons-upload', // позиция страницы, в конце списка 90 ); }); /* * Запускаем сессию, чтобы передавать сообщение о результате * обработки файла после перезагрузки страницы */ add_action('init', function () { if (session_id() == '') { session_start(); } }); /* * Обрабатываем отправленные данные формы */ add_action('admin_post_tokmakov_upload_file', function () { // проверяем защиту nonce и права пользователя $check1 = wp_verify_nonce( $_POST['_wpnonce'], 'tokmakov_upload_file' ); $check2 = current_user_can('upload_files'); ob_start(); if ($check1 && $check2) { // проверка пройдена, можно загружать файл $overrides = ['test_form' => false]; $result = wp_handle_upload( $_FILES['tokmakov_upload_file'], $overrides ); // показываем результаты загрузки файла if (isset($result['error'])) { echo 'Ошибка при загрузке файла'; } else { echo 'Файл был успешно загружен'; } } else { echo 'Проверка не пройдена, файл не загружен'; } $_SESSION['tokmakov_upload_file'] = ob_get_clean(); // после отправки формы делаем редирект, чтобы предотвратить // повторную отправку, если пользователь обновит страницу $redirect = home_url(); if (isset($_POST['redirect'])) { $redirect = $_POST['redirect']; $redirect = wp_validate_redirect($redirect, home_url()); } wp_redirect($redirect); die(); });
Массив $_FILES
, который содержит всю информацию о загруженном файле:
Array ( [tokmakov_upload_file] => Array ( [name] => sunrise.jpg [type] => image/jpeg [tmp_name] => D:\work\temp\phpED8F.tmp [error] => 0 [size] => 490815 ) )
И массив, который возвращает функция wp_handle_upload()
в случае успешной загрузки файла:
Array ( [file] => D:/work/localhost24/www/wp-content/uploads/2019/08/sunrise.jpg [url] => http://www.host24.ru/wp-content/uploads/2019/08/sunrise.jpg [type] => image/jpeg )
Если файл не был загружен, функция возвращает сообщение об ошибке:
Array ( [error] => Извините, этот тип файла недопустим по соображениям безопасности. )
Загрузка одного вложения (attachment)
Хорошо, файл загружать мы умеем, посмотрим, как теперь из файла сделать вложение. Для этого достаточно указать функции media_handle_upload()
ключ массива $_FILES
, который содержит данные о загружаемом файле. И функция сама загрузит файл в директорию uploads
и создаст запись о вложении в таблице wp_posts
в базе данных.
<?php /* * Plugin name: Загрузка файлов * Description: Пример загрузки файлов в панели управления */ /* * Добавляем страницу плагина в панели управления */ add_action('admin_menu', function () { add_menu_page( // содержимое тега title этой страницы 'Загрузка файлов', // название пункта меню для этой страницы 'Загрузка файлов', // права доступа, чтобы был показан этот пункт меню 'upload_files', // уникальный идентификатор меню (страницы) 'tokmakov_upload_page', // функция выводит содержимое этой страницы function () { ?> <div class="wrap"> <h1>Загрузка файлов</h1> <p> Плагин позволяет загружать файлы в директорию <code>/wp-content/uploads</code>. При этом создаются записи в таблице БД <code>wp_posts</code>, то есть эти файлы являются вложениями и доступны для просмотра в библиотеке медиафайлов. </p> <?php if (isset($_SESSION['tokmakov_upload_file'])): ?> <p><?= $_SESSION['tokmakov_upload_file']; ?></p> <?php unset($_SESSION['tokmakov_upload_file']); ?> <?php endif; ?> <?php $action = admin_url('admin-post.php'); $redirect = $_SERVER['REQUEST_URI']; ?> <form action="<?= $action; ?>" method="post" enctype="multipart/form-data"> <?php wp_nonce_field('tokmakov_upload_file'); ?> <input type="hidden" name="action" value="tokmakov_upload_file" /> <input type="hidden" name="redirect" value="<?= $redirect ?>" /> <input type="file" name="tokmakov_upload_file" required /> <input type="submit" value="Загрузить файл" /> </form> </div> <?php }, // иконка для страницы настроек плагина 'dashicons-upload', // позиция страницы, в конце списка 90 ); }); /* * Запускаем сессию, чтобы передавать сообщение о результате * обработки файла после перезагрузки страницы */ add_action('init', function () { if (session_id() == '') { session_start(); } }); /* * Обрабатываем отправленные данные формы */ add_action('admin_post_tokmakov_upload_file', function () { // проверяем защиту nonce и права пользователя $check1 = wp_verify_nonce( $_POST['_wpnonce'], 'tokmakov_upload_file' ); $check2 = current_user_can('upload_files'); ob_start(); if ($check1 && $check2) { // проверка пройдена, можно загружать файл $result = media_handle_upload('tokmakov_upload_file', 0); if (is_wp_error($result)) { echo 'Ошибка при загрузке файла', PHP_EOL; } else { echo 'Файл был успешно загружен', PHP_EOL; } } else { echo 'Проверка не пройдена, файл не загружен'; } $_SESSION['tokmakov_upload_file'] = ob_get_clean(); // после отправки формы делаем редирект, чтобы предотвратить // повторную отправку, если пользователь обновит страницу $redirect = home_url(); if (isset($_POST['redirect'])) { $redirect = $_POST['redirect']; $redirect = wp_validate_redirect($redirect, home_url()); } wp_redirect($redirect); die(); });
Простая загрузка нескольких файлов
Давайте теперь загрузим несколько файлов. Для этого добавим атрибут multiple
для элемента формы и будем «скармливать» функции wp_handle_upload()
по одному загруженному файлу за раз:
<?php /* * Plugin name: Загрузка файлов * Description: Пример загрузки файлов в панели управления */ /* * Добавляем страницу плагина в панели управления */ add_action('admin_menu', function () { add_menu_page( // содержимое тега title этой страницы 'Загрузка файлов', // название пункта меню для этой страницы 'Загрузка файлов', // права доступа, чтобы был показан этот пункт меню 'upload_files', // уникальный идентификатор меню (страницы) 'tokmakov_upload_page', // функция выводит содержимое этой страницы function () { ?> <div class="wrap"> <h1>Загрузка файлов</h1> <p> Плагин позволяет загружать файлы в директорию <code>/wp-content/uploads</code>. Обратите внимание, что загружаются только файлы, это не вложения (attachments). Записи в таблицу <code>wp_posts</code> не добавляются, поэтому в библиотеке медиафайлов эти файлы будут не видны. </p> <?php if (isset($_SESSION['tokmakov_upload_file'])): ?> <ul> <?php foreach ($_SESSION['tokmakov_upload_file'] as $message): ?> <li><?= $message; ?></li> <?php endforeach; ?> </ul> <?php unset($_SESSION['tokmakov_upload_file']); ?> <?php endif; ?> <?php $action = admin_url('admin-post.php'); $redirect = $_SERVER['REQUEST_URI']; ?> <form action="<?= $action; ?>" method="post" enctype="multipart/form-data"> <?php wp_nonce_field('tokmakov_upload_file'); ?> <input type="hidden" name="action" value="tokmakov_upload_file" /> <input type="hidden" name="redirect" value="<?= $redirect ?>" /> <input type="file" name="tokmakov_upload_file[]" multiple required /> <input type="submit" value="Загрузить файлы" /> </form> </div> <?php }, // иконка для страницы настроек плагина 'dashicons-upload', // позиция страницы, в конце списка 90 ); }); /* * Запускаем сессию, чтобы передавать сообщение о результате * обработки файла после перезагрузки страницы */ add_action('init', function () { if (session_id() == '') { session_start(); } }); /* * Обрабатываем отправленные данные формы */ add_action('admin_post_tokmakov_upload_file', function () { // проверяем защиту nonce и права пользователя $check1 = wp_verify_nonce( $_POST['_wpnonce'], 'tokmakov_upload_file' ); $check2 = current_user_can('upload_files'); if ($check1 && $check2) { // перебираем все файлы в цикле и загружаем по одному $messages = []; $overrides = ['test_form' => false]; foreach ($_FILES['tokmakov_upload_file']['name'] as $i => $v) { $file = [ 'name' => $_FILES['tokmakov_upload_file']['name'][$i], 'type' => $_FILES['tokmakov_upload_file']['type'][$i], 'tmp_name' => $_FILES['tokmakov_upload_file']['tmp_name'][$i], 'error' => $_FILES['tokmakov_upload_file']['error'][$i], 'size' => $_FILES['tokmakov_upload_file']['size'][$i], ]; // загружаем очередной файл в директорию uploads $result = wp_handle_upload($file, $overrides); // показываем результаты загрузки очередного файла if (isset($result['error'])) { $messages[] = 'Ошибка при загрузке файла ' . $file['name']; } else { $messages[] = 'Файл ' . $file['name'] . ' успешно загружен'; } } } else { $messages[] = 'Проверка не пройдена, файлы не загружены'; } $_SESSION['tokmakov_upload_file'] = $messages; // после отправки формы делаем редирект, чтобы предотвратить // повторную отправку, если пользователь обновит страницу $redirect = home_url(); if (isset($_POST['redirect'])) { $redirect = $_POST['redirect']; $redirect = wp_validate_redirect($redirect, home_url()); } wp_redirect($redirect); die(); });
Массив $_FILES
, который содержит всю информацию о загруженных файлах:
Array ( [tokmakov_upload_file] => Array ( [name] => Array ( [0] => sunrise-1.jpg [1] => sunrise-2.jpg [2] => sunrise-3.jpg ) [type] => Array ( [0] => image/jpeg [1] => image/jpeg [2] => image/jpeg ) [tmp_name] => Array ( [0] => D:\work\temp\phpC9BC.tmp [1] => D:\work\temp\phpC9CC.tmp [2] => D:\work\temp\phpC9CD.tmp ) [error] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [size] => Array ( [0] => 490815 [1] => 161294 [2] => 207875 ) ) )
Загрузка нескольких вложений (attachments)
Использовать, как и раньше, функцию media_handle_upload()
уже не получится. Она работает напрямую с массивом $_FILES
и в качестве первого аргумента требует индекс массива, который содержит информацию о файле. При этом функция не умеет работать с несколькими файлами. Здесь нам на помощь придет функция media_handle_sideload()
. Будем перебирать все загруженные файлы в цикле и «скармливать» функции media_handle_sideload()
по одному.
<?php /* * Plugin name: Загрузка файлов * Description: Пример загрузки файлов в панели управления */ /* * Добавляем страницу плагина в панели управления */ add_action('admin_menu', function () { add_menu_page( // содержимое тега title этой страницы 'Загрузка файлов', // название пункта меню для этой страницы 'Загрузка файлов', // права доступа, чтобы был показан этот пункт меню 'upload_files', // уникальный идентификатор меню (страницы) 'tokmakov_upload_page', // функция выводит содержимое этой страницы function () { ?> <div class="wrap"> <h1>Загрузка файлов</h1> <p> Плагин позволяет загружать файлы в директорию <code>/wp-content/uploads</code>. При этом создаются записи в таблице БД <code>wp_posts</code>, то есть эти файлы являются вложениями и доступны для просмотра в библиотеке медиафайлов. </p> <?php if (isset($_SESSION['tokmakov_upload_file'])): ?> <ul> <?php foreach ($_SESSION['tokmakov_upload_file'] as $message): ?> <li><?= $message; ?></li> <?php endforeach; ?> </ul> <?php unset($_SESSION['tokmakov_upload_file']); ?> <?php endif; ?> <?php $action = admin_url('admin-post.php'); $redirect = $_SERVER['REQUEST_URI']; ?> <form action="<?= $action; ?>" method="post" enctype="multipart/form-data"> <?php wp_nonce_field('tokmakov_upload_file'); ?> <input type="hidden" name="action" value="tokmakov_upload_file" /> <input type="hidden" name="redirect" value="<?= $redirect ?>" /> <input type="file" name="tokmakov_upload_file[]" multiple required /> <input type="submit" value="Загрузить файлы" /> </form> </div> <?php }, // иконка для страницы настроек плагина 'dashicons-upload', // позиция страницы, в конце списка 90 ); }); /* * Запускаем сессию, чтобы передавать сообщение о результате * обработки файла после перезагрузки страницы */ add_action('init', function () { if (session_id() == '') { session_start(); } }); /* * Обрабатываем отправленные данные формы */ add_action('admin_post_tokmakov_upload_file', function () { // проверяем защиту nonce и права пользователя $check1 = wp_verify_nonce( $_POST['_wpnonce'], 'tokmakov_upload_file' ); $check2 = current_user_can('upload_files'); if ($check1 && $check2) { // перебираем все файлы в цикле и загружаем по одному $messages = []; foreach ($_FILES['tokmakov_upload_file']['name'] as $i => $v) { $file = [ 'name' => $_FILES['tokmakov_upload_file']['name'][$i], 'type' => $_FILES['tokmakov_upload_file']['type'][$i], 'tmp_name' => $_FILES['tokmakov_upload_file']['tmp_name'][$i], 'error' => $_FILES['tokmakov_upload_file']['error'][$i], 'size' => $_FILES['tokmakov_upload_file']['size'][$i], ]; // загружаем очередной файл в директорию uploads $result = media_handle_sideload($file, 0); // показываем результаты загрузки очередного файла if (is_wp_error($result)) { $messages[] = 'Ошибка при загрузке файла ' . $file['name']; } else { $messages[] = 'Файл ' . $file['name'] . ' успешно загружен'; } } } else { $messages[] = 'Проверка не пройдена, файлы не загружены'; } $_SESSION['tokmakov_upload_file'] = $messages; // после отправки формы делаем редирект, чтобы предотвратить // повторную отправку, если пользователь обновит страницу $redirect = home_url(); if (isset($_POST['redirect'])) { $redirect = $_POST['redirect']; $redirect = wp_validate_redirect($redirect, home_url()); } wp_redirect($redirect); die(); });
В случае ошибки при загрузке файла функция media_handle_sideload()
возвращает объект
WP_Error Object ( [errors] => Array ( [upload_error] => Array ( [0] => Извините, этот тип файла недопустим по соображениям безопасности. ) ) [error_data] => Array () )
Если файл загружен успешно, функция возвращает идентификатор вложения.
- WordPress. Загрузка файлов. Часть 3 из 3
- WordPress. Загрузка файлов. Часть 2 из 3
- WordPress. Обработка POST-запросов. Часть 1
- WordPress. API настроек (опций). Часть 4 из 4
- WordPress. Загрузка svg-файлов
- WordPress. Фильтр записей по произвольным полям. Часть 3 из 3
- WordPress. Фильтр записей по произвольным полям. Часть 2 из 3
Поиск: Web-разработка • WordPress • Файл • Форма • Загрузка • Upload • File • wp_handle_upload • media_handle_upload • CMS • POST