Запись в локальные файлы является одной из функциональных возможностей, которые нужны многим плагинам и темам для различных целей. Безопасность — самая важная проблема, над которой нужно позаботиться плагины и темы при записи в локальные файловые системы. WordPress работает с различными хостинговыми сервисами и конфигурациями, поэтому разработчикам становится трудно создавать плагины и темы, которые обращаются к локальным файловым системам для работы в различных средах без ущерба для безопасности.
В этом уроке мы узнаем, как использовать API файловой системы WordPress для доступа к локальным файловым системам, которые заботятся о надлежащих разрешениях для файлов. В процессе мы создадим плагин, который отображает форму с текстовой областью на странице администратора, которая сохраняет содержимое текстовой области в файл.
Зачем использовать API файловой системы WordPress?
Вы можете быть удивлены, почему мы не просто используем функции файловой системы PHP для чтения и записи локальных файлов, а не для изучения и использования совершенно нового набора API-интерфейсов?
Проблема использования API файловой системы PHP заключается в том, что она не заботится о правах доступа к файлам автоматически. Предположим, вы используете службу общего хостинга для размещения своего сайта WordPress, а ваш хостинг-сервер работает под учетной записью «admin» операционной системы. Всякий раз, когда вы создаете файлы с использованием PHP, они принадлежат пользователю «admin». Таким образом, любой другой веб-сайт, размещенный на том же общем хостинге, также может получить доступ к файлам вашего веб-сайта, поскольку они также работают в качестве пользователя «admin», что создает проблему безопасности для вашего сайта. Чтобы защитить нас от этой проблемы, вам нужно изменить владельца файла и разрешения вручную с помощью PHP.
Но когда вы входите в систему, используя SSH или FTP / SFTP для создания файлов, они принадлежат учетной записи пользователя операционной системы, в которую вы вошли как. Если FTP-сервер работает от имени пользователя «admin», а вы вошли в систему как пользователь «narayanprusty», то вновь созданные файлы будут иметь владельца как «narayanprusty», а не «admin».
WordPress представил API файловой системы, который может автоматически заботиться о правах доступа к файлам. Файловая система API была выпущена в WordPress 2.6. WordPress выпустил его для поддержки плагинов, тем и системы обновления ядра, но позже плагины и темы начали использовать его в своих целях.
Как работает API файловой системы?
Файловая система API может записывать в файловые системы с помощью системных вызовов (то есть direct, ftp, ftp socket или ssh2). Он выбирает один из методов на основе того, какой метод создает файлы с надлежащими правами доступа к файлам и какое расширение PHP доступно. Файловая система API сначала проверяет direct
метод, затем ftp
и, наконец, ssh2
.
При использовании FTP или SSH вам необходимо получить учетные данные от вашего пользователя. Файловая система API предоставляет функцию, которая упрощает отображение формы для принятия учетных данных и их хранения.
Создание наших файлов плагинов и каталога
Теперь давайте создадим наш плагин, который отображает текстовую область на странице, где отправка формы сохраняет содержимое текстовой области в локальный файл.
Вот структура каталогов нашего плагина:
--filesystem --filesystem.php --filesystem-demo --demo.txt
Создайте эти файлы и каталоги в каталоге wp-content/plugins
вашей установки WordPress.
Чтобы установить плагин, поместите этот код в файл filesystem.php
:
<?php
Теперь зайдите в вашу админ-панель и установите плагин.
Создание страницы администратора
Далее нам нужна страница нашего администратора, где будет находиться наш пример. Вот код для создания этой страницы и отображения текстовой области. Просто поместите этот код в файл filesystem.php
:
function menu_item() { add_submenu_page("options-general.php", "Demo", "Demo", "manage_options", "demo", "demo_page"); } add_action("admin_menu", "menu_item"); function demo_page() { ?> <div class="wrap"> <h1>Demo</h1> <form method="post"> <?php $output = ""; if(isset($_POST["file-data"])) { $output = write_file_demo($_POST["file-data"]); } else { $output = read_file_demo(); } if(!is_wp_error($output)) { ?> <textarea name="file-data"><?php echo $output; ?></textarea> <?php wp_nonce_field("filesystem-nonce"); ?> <br> <input type="submit"> <?php } else { echo $output->get_error_message(); } ?> </form> </div> <?php }
Вот как работает код:
- Сначала мы добавили страницу в меню «Настройки».
demo_page
— это обратный вызов для отображения содержимого страницы. - Внутри страницы мы отображаем HTML-форму с полями textarea и nonce. Также есть кнопка отправки для отправки формы. Имя текстовой области —
file-data
. Одноразовый номер добавлен для предотвращения атаки CSRF . - Когда страница открыта, мы
read_file_demo
данные сохраненного файла сread_file_demo
функцииread_file_demo
. Когда форма отправлена, мы сохраняем содержимое текстовой области в файл, используя функциюwrite_file_demo
. - Если
read_file_demo
илиwrite_file_demo
возвращает экземпляр объектаWP_Error
, вместо этого мы отобразим сообщение об ошибке.
Обратите внимание, что приведенный выше код сломает ваш сайт WordPress, так как мы еще не создали функции read_file_demo
и write_file_demo
. Давайте создадим их сейчас!
Запись в файл
Вот реализация нашей функции write_file_demo
:
function connect_fs($url, $method, $context, $fields = null) { global $wp_filesystem; if(false === ($credentials = request_filesystem_credentials($url, $method, false, $context, $fields))) { return false; } //check if credentials are correct or not. if(!WP_Filesystem($credentials)) { request_filesystem_credentials($url, $method, true, $context); return false; } return true; } function write_file_demo($text) { global $wp_filesystem; $url = wp_nonce_url("options-general.php?page=demo", "filesystem-nonce"); $form_fields = array("file-data"); if(connect_fs($url, "", WP_PLUGIN_DIR . "/filesystem/filesystem-demo", $form_fields)) { $dir = $wp_filesystem->find_folder(WP_PLUGIN_DIR . "/filesystem/filesystem-demo"); $file = trailingslashit($dir) . "demo.txt"; $wp_filesystem->put_contents($file, $text, FS_CHMOD_FILE); return $text; } else { return new WP_Error("filesystem_error", "Cannot initialize filesystem"); } }
Вот как работает код:
- Сначала мы
$wp_filesystem
к глобальному объекту$wp_filesystem
внутри функции. Этот объект является экземпляром классаWP_Filesystem
. Он отвечает за разоблачение различных методов чтения, создания, записи и удаления файлов. - Затем мы создаем одноразовый URL-адрес нашей страницы формы и массив с именами полей нашей формы.
- Наконец, мы подключаемся к файловой системе с помощью функции
connect_fs
. -
connect_fs
использует функцию request_filesystem_credentials, предоставляемую WordPress, чтобы найти подходящий метод для подключения к файловой системе (прямой, FTP или SSH). В случае FTP или SSH будет отображаться форма для запроса учетных данных от пользователя. В случае прямого метода он просто возвращает true. - Когда форма textarea отправлена и
request_filesystem_credentials
выбирает метод FTP или SSH, тогда мы отображаем форму учетных данных и скрываем полеfile-data
в форме учетных данных. - Первый параметр функции
request_filesystem_credentials
принимает URL-адрес, куда следует перенаправить, когда он получил правильные учетные данные. Редирект имеет тип запроса POST. Последний параметрrequest_filesystem_credentials
— это массив имен полей, которые нужно опубликовать на URL перенаправления. - После отправки формы учетных данных она перенаправляет обратно на исходный URL-адрес отправки формы с правильными именами полей и значениями, введенными пользователем.
- Опять же, весь процесс начинается, и мы выполняем
write_file_demo
. На этот разrequest_filesystem_credentials
имеет учетные данные, поэтому он просто вернет true. - Затем мы используем
$wp_filesystem->find_folder
для ссылки на папку. Затем мы строим полный путь к файлуdemo.txt
. - Мы использовали
$wp_filesystem->put_contents
для записи данных в файл.
Примечание. Если вы попытаетесь использовать $wp_filesystem
объекта $wp_filesystem
без запроса и проверки учетных данных, они не будут работать.
Чтение файла
Вот реализация функции read_file_demo
.
function read_file_demo() { global $wp_filesystem; $url = wp_nonce_url("options-general.php?page=demo", "filesystem-nonce"); if(connect_fs($url, "", WP_PLUGIN_DIR . "/filesystem/filesystem-demo")) { $dir = $wp_filesystem->find_folder(WP_PLUGIN_DIR . "/filesystem/filesystem-demo"); $file = trailingslashit($dir) . "demo.txt"; if($wp_filesystem->exists($file)) { $text = $wp_filesystem->get_contents($file); if(!$text) { return ""; } else { return $text; } } else { return new WP_Error("filesystem_error", "File doesn't exist"); } } else { return new WP_Error("filesystem_error", "Cannot initialize filesystem"); } }
Вот как работает код:
- При чтении файла
demo.txt
мы сначала подключаемся к файловой системе с помощью функцииrequest_filesystem_credentials
. - На этот раз мы не передаем поля формы в последнем параметре, потому что форма не отправлена. Мы просто передаем URL перенаправления, чтобы он был перенаправлен после получения учетных данных.
- Затем мы проверяем, существует ли файл, используя
$wp_filesystem->exists
. Это файл не существует, мы отображаем ошибку. В противном случае мы читаем файл с помощью функции$wp_filesystem->get_contents
и возвращаем содержимое.
Предполагая, что WordPress выбрал FTP в качестве подходящего метода для создания файлов, вот скриншоты всего процесса:
Сначала, когда мы откроем демонстрационную страницу, мы увидим эту форму:
Здесь нам нужно ввести учетные данные FTP или FTPS и отправить их. Как только мы отправим это, мы увидим эту форму:
Была показана пустая текстовая область. Введите текст «Hello World !!!» и отправьте форму. Вы снова увидите форму учетных данных.
Вы должны заполнить его снова, потому что WordPress по умолчанию не хранит пароль FTP (вы можете сделать это в wp-config.php, подробнее об этом позже). Поэтому каждый раз, когда ваш плагин должен работать с файловой системой, он должен запрашивать учетные данные. Теперь его отправка будет перенаправлена обратно на URL перенаправления с именами полей и значениями, представленными ранее. Вот как выглядит текстовая область:
Здесь мы читаем содержимое файла и отображаем его.
Другие методы объекта $wp_filesystem
Объект $wp_filesystem
предоставляет множество других методов для выполнения различных других операций с файлами и каталогами. Мы только что видели запись и чтение n файла. Вы можете найти полный список того, что вы можете сделать, на странице документации WP_Filesystem_Base () .
Давайте проверим некоторые из важных:
- $ wp_filesystem-> delete :
delete
используется для удаления файла или каталога. Вам нужно передать строку, представляющую путь. - $ wp_filesystem-> mkdir :
mkdir
используется для создания каталога. Требуется строка, представляющая родительский каталог. - $ wp_filesystem-> move :
move
используется для перемещения файла. Он принимает два параметра: первый — это путь к файлу, а второй — каталог, куда его нужно переместить. - $ wp_filesystem-> size :
size
возвращает размер файла в байтах. Вам необходимо указать путь к файлу. - $ wp_filesystem-> chmod :
chmod
используется для изменения прав доступа к файлу. Он принимает три аргумента, т.е. путь к файлу, восьмеричное число разрешения и логическое значение, представляющее рекурсию.
Вы можете узнать, какой метод соединения используется WordPress для доступа к файловой системе, используя $wp_filesystem->method
свойство $wp_filesystem->method
.
Постоянное хранение учетных данных
Мы видели, что WordPress не хранит учетные данные FTP или SSH постоянно. Не удобно запрашивать подробности снова и снова. Существует способ постоянного хранения учетных данных с помощью файла wp-config.php
.
Используйте эти параметры для хранения учетных данных FTP и SSH:
- FTP_HOST : имя хоста сервера.
- FTP_USER : имя пользователя для подключения.
- FTP_PASS : пароль, используемый при подключении
- FTP_PUBKEY : путь открытого ключа, который будет использоваться при использовании соединения SSH2.
- FTP_PRIKEY : путь закрытого ключа, который будет использоваться при использовании соединения SSH2.
Вывод
В этой статье мы увидели процесс создания страницы администратора, которая обращается к нашей файловой системе с помощью API файловой системы WordPress. Если вы пытаетесь получить доступ к файловой системе в фоновом процессе (например, с помощью задания cron), тогда невозможно отобразить форму учетных данных, если это необходимо, в этом случае вам необходимо убедиться, что вы уведомили своего пользователя. поместить учетные константы в файл wp-config.php
. Вы можете пойти дальше и поэкспериментировать с этим API и поделиться своим опытом с нами ниже.