Обзор файловых браузеров на PHP и их реализация
Файловый браузер на PHP позволяет пользователю просматривать содержимое серверных директорий через веб-интерфейс. Такое решение часто используется в файловых менеджерах хостинг-панелей, системах управления контентом или для организации временного доступа к файлам. В статье рассматриваются различные подходы к реализации, начиная от простого скрипта и заканчивая интеграцией готовых библиотек. Примеры кода помогут разобраться в деталях и избежать типичных ошибок.
Основное решение: простой файловый браузер с навигацией
Самый простой и эффективный способ создать файловый браузер - использовать встроенные функции PHP для обхода директорий. Ниже представлен код, который выводит список файлов и папок в текущей директории, позволяет переходить по папкам и возвращаться назад. Решение безопасно, так как проверяет, что запрошенный путь является поддиректорией разрешенной корневой папки.
<?php
$root = '/var/www/files'; // корневая директория
$path = isset($_GET['dir']) ? realpath($root . '/' . $_GET['dir']) : $root;
if (!$path || strpos($path, $root) !== 0) {
die('Недопустимый путь');
}
$items = scandir($path);
echo '<ul>';
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$fullPath = $path . '/' . $item;
$relative = substr($fullPath, strlen($root)+1);
if (is_dir($fullPath)) {
echo '<li><a href="?dir=' . urlencode($relative) . '">' . htmlspecialchars($item) . '/</a></li>';
} else {
echo '<li>' . htmlspecialchars($item) . ' (' . filesize($fullPath) . ' байт)</li>';
}
}
echo '</ul>';
if ($path != $root) {
$parent = dirname($_GET['dir']);
$parent = ($parent == '.') ? '' : $parent;
echo '<a href="?dir=' . urlencode($parent) . '">Наверх</a>';
}
?>
Php file browser (файловый браузер на php)
Объяснение шагов:
- Установка корневой директории $root - все операции ограничены ею.
- Получение текущей директории из параметра dir, проверка через realpath и strpos для защиты от path traversal.
- Использование scandir для получения списка файлов.
- Вывод элементов: папки отображаются как ссылки, файлы - как текст с размером.
- Ссылка «Наверх» для возврата в родительскую директорию.
Типичные ошибки:
- Необработанный path traversal: злоумышленник может указать ?dir=../../etc/passwd. Решение - проверка, что разрешенный путь начинается с корневого.
- Проблемы с кодировкой: имена файлов в UTF-8 могут некорректно отображаться. Используйте htmlspecialchars и убедитесь, что страница передает UTF-8.
- Права доступа: скрипт может не иметь прав на чтение директории. Следует проверять is_readable и выводить сообщение об ошибке.
Как отобразить файлы в виде дерева с помощью рекурсии?
Для древовидного отображения подходит рекурсивный обход. Каждая папка раскрывается в зависимости от параметра. Пример:
function tree($dir, $root, $depth = 0) {
$items = scandir($dir);
echo '<ul>';
foreach ($items as $item) {
if ($item[0] == '.') continue;
$path = $dir . '/' . $item;
$relative = substr($path, strlen($root)+1);
$indent = str_repeat(' ', $depth*4);
if (is_dir($path)) {
echo '<li>' . $indent . '<a href="?dir=' . urlencode($relative) . '">' . htmlspecialchars($item) . '/</a>';
if (isset($_GET['expand']) && $_GET['expand'] == $relative) {
tree($path, $root, $depth+1);
}
echo '</li>';
} else {
echo '<li>' . $indent . htmlspecialchars($item) . '</li>';
}
}
echo '</ul>';
}
File storage php (хранение файлов в php)
Вызов: tree($root, $root) с передачей параметра expand для раскрытия нужной папки.
- Большое количество папок может замедлить работу. Можно использовать кэширование.
- Рекурсия может превысить лимит вложенности. Для глубоких деревьев применяют итеративный обход.
Как дать пользователю возможность загружать файлы на сервер?
Добавление формы загрузки с обработкой на PHP. Файлы сохраняются в текущую директорию.
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Загрузить">
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$target = $path . '/' . basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], $target)) {
echo 'Файл загружен';
} else {
echo 'Ошибка загрузки';
}
}
?>
Php file manager (файловый менеджер на php)
- Ограничение размера через php.ini (upload_max_filesize, post_max_size).
- Проверка типа файла для безопасности: mime_content_type или расширение.
- Перезапись существующих файлов - необходимо добавить проверку.
Как сделать навигацию по папкам без перезагрузки страницы?
AJAX запрос к файловому браузеру, который возвращает HTML. Пример на JavaScript (fetch):
function loadDir(dir) {
fetch('browser.php?dir=' + encodeURIComponent(dir))
.then(response => response.text())
.then(html => {
document.getElementById('filelist').innerHTML = html;
});
}
Серверный код аналогичен основному, но возвращает только список, без всей страницы.
- Необходимо корректно обрабатывать ошибки HTTP.
- Поддержка истории браузера через pushState или hash.
Как быстро развернуть полнофункциональный файловый менеджер?
Готовая библиотека elFinder (на базе jQuery) предоставляет готовый интерфейс с drag-and-drop, редактированием, правами доступа. Подключение:
// elfinder.html
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/elfinder@2.1.57/css/elfinder.min.css">
<script src="//cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/elfinder@2.1.57/js/elfinder.min.js"></script>
<div id="elfinder"></div>
<script>
$('#elfinder').elfinder({
url: 'php/connector.minimal.php'
});
</script>
Серверный коннектор обычно входит в состав elFinder. Настраивается корневая директория и права доступа.
- Требуется jQuery и дополнительные ресурсы.
- Необходимо настроить коннектор под свои нужды (аутентификация, ограничения).
- Версии elFinder могут иметь уязвимости, следует обновлять.
Как ограничить доступ к файловому браузеру только для авторизованных пользователей?
Простая проверка сессии перед началом работы:
session_start();
if (!isset($_SESSION['user'])) {
header('HTTP/1.0 403 Forbidden');
exit('Доступ запрещен');
}
// далее код браузера
Для более гибкого управления можно использовать библиотеки аутентификации (например, PHP-Auth).
- Не забывайте о защите от CSRF, если браузер выполняет изменения.
- Хранение сессий должно быть безопасным.
Расширенные примеры реализации файлового браузера на PHP
Рекурсивный обход с сортировкой и фильтрацией
function listFilesRecursive($dir, $filter = null) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
);
$files = [];
foreach ($iterator as $file) {
if ($filter && !preg_match($filter, $file->getFilename())) continue;
$files[] = $file->getPathname();
}
sort($files);
return $files;
}
// Пример: $files = listFilesRecursive('/var/www/files', '/\.php$/');
Результат - массив с путями, отсортированный по имени. Можно дополнить группировкой по расширению.
Операции с файлами: переименование и удаление
// Переименование
if (isset($_POST['rename'], $_POST['old'], $_POST['new'])) {
$old = $root . '/' . $_POST['old'];
$new = $root . '/' . dirname($_POST['old']) . '/' . basename($_POST['new']);
if (rename($old, $new)) {
echo 'Успешно переименовано';
} else {
echo 'Ошибка переименования';
}
}
// Удаление (только файлы или пустые папки)
if (isset($_POST['delete'])) {
$target = $root . '/' . $_POST['delete'];
if (is_file($target)) {
unlink($target);
} elseif (is_dir($target) && !(new FilesystemIterator($target))->valid()) {
rmdir($target);
} else {
echo 'Папка не пуста';
}
}
Важно проверять права и путь, чтобы не выйти за корневую директорию.
Генерация миниатюр изображений
function thumbnail($path, $width = 100, $height = 100) {
list($w, $h) = getimagesize($path);
$src = imagecreatefromstring(file_get_contents($path));
$thumb = imagecreatetruecolor($width, $height);
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $width, $height, $w, $h);
ob_start();
imagejpeg($thumb);
return ob_get_clean();
}
// Вывод: header('Content-Type: image/jpeg'); echo thumbnail('photo.jpg');
Результат - JPEG изображение указанного размера. Для экономии места можно кэшировать миниатюры.
Интеграция с базой данных для хранения метаданных
// При сканировании директории записывать в БД размер, дату, md5
$stmt = $pdo->prepare('INSERT INTO files (path, size, hash) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE size=VALUES(size), hash=VALUES(hash)');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root)) as $file) {
$path = $file->getPathname();
$size = $file->getSize();
$hash = md5_file($path);
$stmt->execute([$path, $size, $hash]);
}
Позволяет быстро искать дубликаты, отслеживать изменения.
RESTful API для файлового браузера
// GET /api/list?dir=subfolder
header('Content-Type: application/json');
$path = realpath($root . '/' . $_GET['dir']);
if (!$path || strpos($path, $root) !== 0) {
http_response_code(403);
echo json_encode(['error' => 'Forbidden']);
exit;
}
$items = array_diff(scandir($path), ['.', '..']);
$result = [];
foreach ($items as $item) {
$full = $path . '/' . $item;
$result[] = [
'name' => $item,
'type' => is_dir($full) ? 'dir' : 'file',
'size' => is_file($full) ? filesize($full) : null,
'path' => substr($full, strlen($root)+1)
];
}
echo json_encode($result);
Ответ в JSON для клиентского приложения. Пример использования с fetch на фронтенде.