Создание файлового менеджера на PHP: от простого скрипта до фреймворка
Файловый менеджер на PHP: принципы и реализация
Базовый самописный файловый менеджер
Самый эффективный способ создания PHP-файлового менеджера для типовых задач - написать компактный скрипт, выполняющий основные операции: просмотр, создание, удаление, переименование, загрузку файлов. Такой подход даёт полный контроль над функциональностью и безопасностью.
Пример простейшего менеджера, выводящего содержимое текущей директории:
<?php
$dir = __DIR__;
$items = scandir($dir);
echo "<ul>";
foreach ($items as $item) {
if ($item != '.' && $item != '..') {
echo "<li>" . htmlspecialchars($item) . "</li>";
}
}
echo "</ul>";
?>
Php file browser (файловый браузер на php)
Данный код выводит список файлов и папок в корне скрипта. Для навигации по папкам необходимо добавить параметр dir в URL и обрабатывать его с проверкой на выход за пределы разрешённой директории.
Типичная ошибка:
Попытка использовать $_GET['dir'] без валидации ведёт к Path Traversal атаке. Решение - проверять, что конечный путь начинается с разрешённой корневой директории, и удалять подстроки .. при помощи realpath().
Пошаговая реализация операций:
- Создание папки:
mkdir($_GET['newfolder'], 0775);с проверкой прав. - Загрузка файла: форма с
enctype="multipart/form-data", сохранение черезmove_uploaded_file. Убедиться, что тип файла разрешён. - Удаление:
unlink($filepath)для файлов,rmdir($dirpath)для пустых папок. Для непустых папок требуется рекурсивное удаление. - Переименование:
rename($old, $new);с проверкой на существование нового имени.
Такой минимальный файловый менеджер подходит для администрирования одного сайта. При необходимости его легко расширить добавлением AJAX, многоязычности и авторизации.
Как применить готовый файловый менеджер Tiny File Manager?
Если требуется быстрое внедрение без написания собственного кода, популярным вариантом является Tiny File Manager - одностраничное веб-приложение с поддержкой AJAX, изображений, файловых операций и мультиязычности.
// Пример структуры для установки
- tinyfilemanager.php // главный скрипт
- translations/ // файлы переводов
- config.php // настройки (опционально)
File storage php (хранение файлов в php)
Установка: скачать скрипт, поместить на сервер, изменить пароль в конфигурации. Открыть в браузере - менеджер готов к работе.
Проблема:
По умолчанию Tiny File Manager имеет один логин/пароль, что неудобно для нескольких администраторов. Решение - настроить аутентификацию через сессии или OAuth.
Ещё одна распространённая ошибка: если скрипт не показывает файлы, возможно, не установлены необходимые PHP расширения (например, mbstring, zip).
Как организовать файловый менеджер с AJAX для динамической работы без перезагрузки страницы?
AJAX улучшает пользовательский опыт. Реализация на базе jQuery и PHP позволяет загружать список файлов, удалять и создавать папки асинхронно.
// JavaScript (фрагмент)
$('#loadFolder').on('click', function() {
$.get('ajax.php', { action: 'list', dir: currentDir }, function(data) {
$('#fileList').html(data);
});
});
Php file manager (файловый менеджер на php)
// PHP (ajax.php)
$dir = realpath($_GET['dir']) ?: '.';
$items = scandir($dir);
$output = '<ul>';
foreach ($items as $item) {
if ($item[0] != '.') {
$output .= '<li data-path="' . $dir . '/' . $item . '">' . htmlspecialchars($item) . '</li>';
}
}
$output .= '</ul>';
echo $output;
При таком подходе нужно корректно обрабатывать запросы (действие list, delete, rename) и возвращать JSON или HTML.
Типичная ошибка:
При большом количестве файлов AJAX-запросы могут выполняться долго. Решение - использовать пагинацию на сервере и ленивую загрузку.
Ещё одна проблема: обновление списка после действий требует повторного запроса, что можно решить возвратом нового HTML после каждой операции.
Как обеспечить безопасность файлового менеджера, исключив доступ к системным файлам?
Безопасность - критический аспект. Основные меры:
- Ограничить корневую директорию, за пределами которой нельзя перемещаться (chroot).
- Проверять расширения загружаемых файлов (нельзя загружать .php, .phtml и т.д., если нет необходимости).
- Использовать токены CSRF для всех операций.
- Требовать аутентификацию и сессии.
// Проверка пути на основе белого списка
$allowedBase = realpath(__DIR__ . '/files');
$userPath = realpath($_GET['dir']);
if (strpos($userPath, $allowedBase) !== 0) {
die('Недопустимый путь');
}
Это предотвращает выход за пределы разрешённой папки.
Распространённая ошибка:
Использование basename() без realpath() не защищает от атак вида ../../../etc/passwd. Всегда нормализуйте путь.
Ещё частая проблема - загрузка исполняемых скриптов. Решить можно как проверкой расширения, так и хранением загруженных файлов вне DocumentRoot.
Как встроить файловый менеджер в Laravel (или другой фреймворк)?
Для Laravel популярен пакет Laravel Filemanager (unisharp/laravel-filemanager), который предоставляет веб-интерфейс для управления файлами и интеграцию с редакторами (TinyMCE, CKEditor).
// Установка
composer require unisharp/laravel-filemanager
// Публикация конфигурации
php artisan vendor:publish --tag=lfm_config
// Маршруты (в routes/web.php)
Route::group(['middleware' => ['web', 'auth']], function () {
\UniSharp\LaravelFilemanager\Lfm::routes();
});
После этого файловый менеджер доступен по адресу /laravel-filemanager. Настройка разрешённых расширений, размера и количества файлов производится в конфигурационном файле config/lfm.php.
Типичная проблема:
Конфликт с другими маршрутами - убедитесь, что middleware и префиксы не пересекаются. Также возможна ошибка 403, если не настроены права доступа к папке storage/app/public.
Решение: создать символическую ссылку php artisan storage:link и выставить права 775 на директорию хранения.
Каждый из вариантов применим в зависимости от проекта - от небольшого скрипта до крупного портала на фреймворке. Выбор зависит от требований к скорости разработки, безопасности и гибкости.
Расширенные примеры реализации файлового менеджера на PHP
1. Полный пример самописного файлового менеджера с поддержкой навигации, загрузки и удаления
Ниже представлен скрипт, который показывает содержимое папки, позволяет переходить между папками, загружать файлы, удалять их и создавать новые папки. Все операции защищены минимальной проверкой.
<?php
session_start();
// Корневая разрешённая директория
$root = realpath(__DIR__ . '/user_files');
// Текущая директория (из GET или корень)
$current = isset($_GET['dir']) ? realpath($_GET['dir']) : $root;
if (strpos($current, $root) !== 0) {
die('Доступ запрещён');
}
// Создание папки
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['newfolder'])) {
$newFolder = $current . '/' . basename($_POST['newfolder']);
if (!file_exists($newFolder)) {
mkdir($newFolder, 0775, true);
}
header('Location: ?dir=' . urlencode($current));
exit;
}
// Удаление
if (isset($_GET['delete'])) {
$target = $current . '/' . basename($_GET['delete']);
if (is_file($target)) {
unlink($target);
} elseif (is_dir($target)) {
array_map('unlink', glob($target . '/*')); // удаляем файлы внутри
rmdir($target);
}
header('Location: ?dir=' . urlencode($current));
exit;
}
// Загрузка
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$uploadPath = $current . '/' . basename($_FILES['file']['name']);
move_uploaded_file($_FILES['file']['tmp_name'], $uploadPath);
header('Location: ?dir=' . urlencode($current));
exit;
}
?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Файловый менеджер</title></head>
<body>
<h2>Файлы в <?= htmlspecialchars(str_replace($root, '', $current) ?: '/') ?></h2>
<ul>
<?php if ($current != $root): ?>
<li><a href="?dir=<?= urlencode(dirname($current)) ?>">(..) Наверх</a></li>
<?php endif;
foreach (scandir($current) as $item):
if ($item[0] == '.') continue; ?>
<li>
<?php if (is_dir($current . '/' . $item)): ?>
<a href="?dir=<?= urlencode($current . '/' . $item) ?>"><?= htmlspecialchars($item) ?>/</a>
<?php else: ?>
<?= htmlspecialchars($item) ?>
<?php endif; ?>
[<a href="?dir=<?= urlencode($current) ?>&delete=<?= urlencode($item) ?>" onclick="return confirm('Удалить?')">X</a>]
</li>
<?php endforeach; ?>
</ul>
<h3>Создать папку</h3>
<form method="post">
<input type="text" name="newfolder" placeholder="Имя папки" required>
<button type="submit">Создать</button>
</form>
<h3>Загрузить файл</h3>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" required>
<button type="submit">Загрузить</button>
</form>
</body>
</html>
Результат работы (пример вывода):
Файлы в /images/ - (..) Наверх - photo2024.jpg [X] - logo.png [X] - diagrams/ [X]
В этом примере реализованы базовые операции, но нет проверки типов файлов при загрузке и нет защиты CSRF. Для продакшена требуется дополнить.
2. Пример настройки Tiny File Manager с кастомной аутентификацией
Вместо встроенного пароля можно подключить сессию пользователя сайта. В файле config.php (или прямо в tinyfilemanager.php) изменить проверку:
// Вместо проверки пароля
if (!isset($_SESSION['user'])) {
header('Location: /login.php');
exit;
}
// Установка корневой директории в зависимости от пользователя
$root_path = 'files/' . $_SESSION['user_id']; // каждый пользователь в своей папке
if (!is_dir($root_path)) mkdir($root_path, 0775, true);
Это позволит интегрировать менеджер в уже существующую систему авторизации.
3. AJAX-загрузка папок (фрагмент)
Для асинхронной загрузки содержимого папки при клике на неё можно использовать следующий код jQuery и PHP:
// JS
$('.folder').on('click', function(e) {
e.preventDefault();
var path = $(this).data('path');
$.get('ajax_list.php', { dir: path }, function(html) {
$('#files-container').html(html);
});
});
// PHP (ajax_list.php)
$root = realpath(__DIR__ . '/files');
$dir = isset($_GET['dir']) ? realpath($_GET['dir']) : $root;
if (strpos($dir, $root) !== 0) die('Ошибка');
$items = array_diff(scandir($dir), ['.', '..']);
$output = '<ul class="file-list">';
foreach ($items as $item) {
$fullPath = $dir . '/' . $item;
$isDir = is_dir($fullPath);
$output .= '<li class="' . ($isDir ? 'folder' : 'file') . '" data-path="' . htmlspecialchars($fullPath) . '">';
$output .= ($isDir ? '<a href="#">' . htmlspecialchars($item) . '/</a>' : htmlspecialchars($item));
$output .= '</li>';
}
$output .= '</ul>';
echo $output;
Результат - динамическая навигация без перезагрузки страницы.
4. Пример использования файлового менеджера в Laravel для выбора файла
Если требуется встроить диалог выбора файла (например, для TinyMCE), маршруты и настройки уже созданы после установки пакета. Пример вызова в шаблоне:
// В Blade-шаблоне
<textarea id="my-editor"></textarea>
<script>
tinymce.init({
selector: '#my-editor',
file_picker_callback: function(callback, value, meta) {
var x = window.innerWidth / 2;
var y = window.innerHeight / 2;
var url = '/laravel-filemanager?type=' + meta.filetype;
tinymce.activeEditor.windowManager.openUrl({
title: 'Файловый менеджер',
url: url,
width: x,
height: y,
onMessage: function(dialogApi, details) {
callback(details.content);
dialogApi.close();
}
});
}
});
</script>
После выбора файла в менеджере он вставляется в редактор.