Функции файлов Albireo CMS
Функция checkRealFile
Функция для безопасной проверки существования файла и корректности пути.
Сигнатура
function checkRealFile(string $dir, string $file): string|false
Аргументы
- string
$dir - Базовый каталог (должен быть абсолютным путем)
- string
$file - Имя файла или относительный путь внутри каталога
Возвращаемое значение
Абсолютный путь к файлу (string) или false если:
- Файл не существует
- Путь содержит относительные переходы
- Пути не совпадают после нормализации
Алгоритм работы
- Объединяет базовый каталог и путь к файлу
- Приводит разделители путей к системному формату
- Проверяет существование файла через
realpath() - Сравнивает реальный путь с ожидаемым
Примеры использования
// Проверка файла в Linux
$valid = checkRealFile('/var/www/', 'public/index.php');
// Проверка файла в Windows
$valid = checkRealFile('C:\\www\\', 'public\\index.php');
// Проверка безопасности (защита от path traversal)
if (checkRealFile('/safe/dir/', '../secret.txt') === false) {
die('Недопустимый путь!');
}
Особенности безопасности
- Защищает от атак path traversal
../ - Нормализует разделители путей
- Проверяет точное соответствие путей
- Не подвержена проблемам с относительными путями
Рекомендации
- Всегда используйте для проверки загружаемых файлов
- Проверяйте результат строго (=== false)
- Передавайте только доверенные базовые каталоги
- Для работы с путями используйте
DIRECTORY_SEPARATOR
Функция checkUrlAsRealFile
Функция для безопасной проверки соответствия URL реальным файлам в файловой системе.
Сигнатура
function checkUrlAsRealFile(string $url): string|false
Аргументы
- string
$url - Полный HTTP/HTTPS URL для проверки (например
https://example.com/path/file.txt)
Возвращаемое значение
Абсолютный путь к файлу (string) или false если:
- URL принадлежит другому домену
- Файл не существует
- Путь выходит за пределы
BASE_DIR
Алгоритм работы
- Проверяет что URL начинается с
http://илиhttps://+FRONT_URL_NAME - Заменяет домен на
BASE_DIRдля получения файлового пути - Проверяет существование файла через
realpath() - Убеждается что путь находится внутри
BASE_DIR - Для каталогов добавляет trailing slash
Примеры использования
// Проверка существующего файла
$path = checkUrlAsRealFile('https://example.com/images/logo.png');
// Проверка несуществующего файла
if (checkUrlAsRealFile('https://example.com/nonexistent.txt') === false) {
echo 'Файл не существует';
}
// Попытка доступа к другому домену
checkUrlAsRealFile('https://another.com/secret.txt'); // false
Рекомендации
- Используйте для проверки пользовательских URL перед доступом к файлам
- Всегда проверяйте результат на === false
Функция contentFile
Обертка для чтения и обработки содержимого файлов через стандартную цепочку преобразований.
Сигнатура
function contentFile(string $fn, array $pageData = []): string
Аргументы
- string
$fn - Путь к файлу для чтения. Должен быть доступен для чтения.
- array
$pageData - Настройки обработки контента (передаются в
processingContent()):- protect-pre: bool - защищать ли HTML в тегах PRE/CODE
- parser: string - список парсеров через запятую
- text-function: string - список функций через запятую
Возвращаемое значение
Обработанное содержимое файла (string).
Алгоритм работы
- Читает содержимое файла через
getContentFile() - Передает содержимое и настройки в
processingContent() - Возвращает обработанный результат
Примеры использования
// Чтение шаблона без обработки
echo contentFile('/templates/header.php');
// Чтение с обработкой Markdown
$article = contentFile('/content/article.md', [
'parser' => 'markdown'
]);
// Чтение с защитой кода и обработкой
$codeExample = contentFile('/examples/demo.html', [
'protect-pre' => true,
'text-function' => 'htmlspecialchars'
]);
Функция copyDir
Рекурсивное копирование каталогов с сохранением структуры подкаталогов.
Сигнатура
function copyDir(string $src, string $dst): void
Аргументы
- string
$src - Абсолютный путь к исходному каталогу. Должен существовать и быть доступным для чтения.
- string
$dst - Абсолютный путь к целевому каталогу. Будет создан (включая все подкаталоги) если не существует.
Примеры использования
// Простое копирование
copyDir('/var/www/old-site', '/var/www/new-site');
// Копирование с предварительной проверкой
if (file_exists($sourceDir)) {
copyDir($sourceDir, $backupDir . date('Y-m-d'));
}
Обработка ошибок
- Генерирует исключение если исходный каталог не существует
- Может генерировать предупреждения при проблемах с правами доступа
- Рекомендуется использовать try-catch для обработки ошибок
Функция deleteDir
Полное рекурсивное удаление каталога со всем его содержимым.
Сигнатура
function deleteDir(string $dir): bool
Аргументы
- string
$dir - Абсолютный путь к удаляемому каталогу. Должен существовать и быть доступным для записи.
Возвращаемое значение
bool: true при успешном удалении, false при возникновении ошибки.
Примеры использования
// Удаление временного каталога
deleteDir('/tmp/old_cache');
// Удаление с обработкой ошибок
try {
deleteDir('/var/www/old_project');
} catch (RuntimeException $e) {
error_log('Ошибка удаления: ' . $e->getMessage());
}
Обработка ошибок
- Проверяет существование каталога перед удалением
- Генерирует исключение при невозможности прочитать/удалить содержимое
- Возвращает false при неудачном удалении основного каталога
Функция dirToArray
Рекурсивное сканирование файловой структуры с возможностью фильтрации по расширениям.
Сигнатура
function dirToArray(string $dir, array $allowExt = []): array
Аргументы
- string
$dir - Абсолютный путь к сканируемому каталогу
- array
$allowExt - Массив разрешенных расширений файлов (например
['php', 'jpg']). Пустой массив - без фильтрации.
Возвращаемое значение
Ассоциативный массив (array), где:
- Ключи - имена подкаталогов
- Значения - массивы содержимого подкаталогов
- Файлы - элементы массива
Формат результата
Пример возвращаемого массива:
[
'subdir1' => [
'file1.txt',
'file2.php',
'nested' => [
'image.jpg'
]
],
'file3.html'
]
Примеры использования
// Полное сканирование
$fullTree = dirToArray('/var/www/project');
// С фильтрацией изображений
$images = dirToArray('/var/www/images', ['jpg', 'png', 'gif']);
// Визуализация структуры
function renderTree(array $tree, int $level = 0) {
foreach ($tree as $key => $value) {
if (is_array($value)) {
echo str_repeat(' ', $level) . "[$key]" . PHP_EOL;
renderTree($value, $level + 1);
} else {
echo str_repeat(' ', $level) . "$value" . PHP_EOL;
}
}
}
renderTree(dirToArray('/path/to/dir'));
$mapDir = dirToArray(PAGES_DIR, ['php', 'jpg']);
$outText = tree($mapDir);
// pr($outText); // для просмотра структуры
// функция обхода массива
function tree($data, $tab = '', $root = '')
{
$result = '';
foreach ($data as $key => $value) {
if (is_array($value)) {
// это каталог
$result .= $tab . DIRECTORY_SEPARATOR . $key . LF;
$old_root = $root;
$root = $root . $key . DIRECTORY_SEPARATOR;
$result .= tree(data: $value, tab: $tab . str_repeat(' ', 4), root: $root);
$root = $old_root;
} else {
// это файл
$result .= $tab . $root . $value . LF;
}
}
return $result;
}
Функция dirToArrayFlat
Создает плоскую структуру файлов, сгруппированных по подкаталогам, с поддержкой фильтрации.
Сигнатура
function dirToArrayFlat(string $scanDir, string $mask = '*.*', array $exclude = []): array
Аргументы
- string
$scanDir - Абсолютный путь к каталогу для сканирования
- string
$mask - Маска поиска файлов в синтаксисе
glob():*- любое количество символов?- один символ{ext1,ext2}- альтернативные расширения
- array
$exclude - Массив подкаталогов для исключения (относительные пути от
$scanDir)
Возвращаемое значение
Ассоциативный массив (array), где:
- Ключи - относительные пути подкаталогов (включая / для корня)
- Значения - массивы имен файлов с относительными путями
Особенности работы
- Рекурсивно сканирует все подкаталоги
- Применяет естественную сортировку (
natsort) к результатам - Исключает указанные подкаталоги (полные пути)
- Поддерживает сложные маски через
GLOB_BRACE - Возвращает относительные пути (без
$scanDir)
Примеры использования
// Получить все файлы проекта
$allFiles = dirToArrayFlat('/var/www/project');
// Только PHP и HTML файлы, исключая тестовые каталоги
$codeFiles = dirToArrayFlat('/var/www', '*.{php,html}', ['tests', 'vendor']);
// Получить структуру для отображения
foreach (dirToArrayFlat('/path') as $dir => $files) {
echo "Каталог $dir:\n";
foreach ($files as $file) {
echo "- $file\n";
}
}
Формат результата
Пример возвращаемого массива:
[
'/' => [
'index.php',
'config.ini'
],
'/subdir' => [
'subdir/file1.txt',
'subdir/image.jpg'
],
'/subdir/nested' => [
'subdir/nested/script.php'
]
]
Функция dirToArrayFlat2
Альтернативная версия dirToArrayFlat с плоской структурой и особой сортировкой.
Сигнатура
function dirToArrayFlat2(string $scanDir, string $mask = '*.*', array $exclude = []): array
Ключевые особенности
- Возвращает простой массив относительных путей вместо группировки по каталогам
- Сортировка выполняется по именам файлов (без учета путей)
Отличия от dirToArrayFlat
| dirToArrayFlat | dirToArrayFlat2 |
|---|---|
| Группирует по каталогам | Плоская структура |
| Сортировка внутри каталогов | Общая сортировка по именам файлов |
| Возвращает ассоциативный массив | Возвращает простой массив |
Формат результата
Пример возвращаемого массива:
[
'docs/file1.txt',
'images/photo1.jpg',
'images/photo2.jpg',
'logs/error_20230101.log',
'logs/error_20230102.log'
]
Примеры использования
// Получить все изображения, отсортированные по именам
$images = dirToArrayFlat2('/var/www/images', '*.{jpg,png}');
// Работа с файлами, имеющими временные метки
$logs = dirToArrayFlat2('/var/log', '*.log');
// Новые файлы (с большими временными метками) будут в конце массива
$latestLog = end($logs);
Рекомендации
- Подходит для обработки логов и временных файлов
- Для группировки по каталогам используйте
dirToArrayFlat - Используйте естественную сортировку для числовых имен
Функция findFile
Поиск файла в нескольких возможных каталогах с возвратом первого найденного.
Сигнатура
function findFile(string $file, array $dirs): string|false
Аргументы
- string
$file - Имя искомого файла (может содержать относительный путь)
- array
$dirs - Массив каталогов для поиска (должны быть абсолютными путями)
Возвращаемое значение
Полный абсолютный путь к файлу (string) или false, если файл не найден ни в одном каталоге.
Примеры использования
// Поиск языкового файла
$langFile = findFile('ru.json', [
'/var/www/app/lang',
'/usr/local/share/lang',
'./lang'
]);
// Поиск с fallback каталогами
$template = findFile('footer.tpl', [
'/var/www/templates/custom',
'/var/www/templates/default'
]) or die('Template not found');
Особенности
- Проверяет каталоги в порядке их указания в массиве
- Использует безопасную проверку через
checkRealFile() - Поддерживает относительные пути в имени файла
- Возвращает абсолютный путь к найденному файлу
Типичные сценарии использования
- Поиск конфигурационных файлов в нескольких расположениях
- Реализация системы тем/шаблонов с fallback
- Загрузка ресурсов из разных возможных каталогов
- Поиск одноименных модулей в нескольких директориях
Функция getContentFile
Изолированное подключение PHP-файла с захватом вывода.
Сигнатура
function getContentFile(string $fn): string
Аргументы
- string
$fn - Абсолютный путь к PHP-файлу, который требуется подключить
Возвращаемое значение
Строка (string) с содержимым, которое сгенерировал подключенный файл.
Если файл не существует, возвращается пустая строка.
Примеры использования
// Подключение шаблона $header = getContentFile(__DIR__ . '/templates/header.php'); echo $header;
Функция getExtension
Универсальная функция для работы с расширениями файлов.
Сигнатура
function getExtension(string $file, array $allowExt = []): string|bool
Аргументы
- string
$file - Имя файла или путь к файлу. Может содержать путь (например:
'/path/to/file.txt') - array
$allowExt - Массив разрешенных расширений (без точки). Например:
['jpg', 'png', 'gif']
Возвращаемое значение
Может возвращать два типа значений:
string: расширение файла в нижнем регистре (если$allowExtне указан)bool: true если расширение в списке разрешенных, false если нет (если$allowExtуказан)
Примеры использования
// Получение расширения
echo getExtension('archive.tar.gz'); // 'gz'
// Проверка расширения
if (getExtension($uploadedFile, ['jpg', 'jpeg', 'png'])) {
// файл имеет допустимое расширение
}
// Фильтрация файлов по расширению
$images = array_filter($files, function($file) {
return getExtension($file, ['jpg', 'png', 'gif']);
});
Особенности
- Всегда возвращает расширение в нижнем регистре
- Работает с файлами, имеющими несколько точек в имени
- Для файлов без расширения вернет пустую строку
- Чувствительна к регистру при проверке разрешенных расширений
Функция getSubDirs
Функция getSubDirs рекурсивно сканирует указанный каталог и возвращает список всех вложенных в него подкаталогов. Предоставляет опцию для исключения "служебных" директорий, имена которых начинаются с символа подчеркивания.
Сигнатура
function getSubDirs(string $baseDir, bool $excludeUnderlineDir = false): array
Аргументы
- string
$baseDir - Полный путь к исходному каталогу, который необходимо просканировать.
- bool
$excludeUnderlineDir(необязательный) - Если
true, каталоги, имена которых начинаются с символа_(например,_cache,_private), будут проигнорированы. По умолчаниюfalse.
Результат
Возвращает индексированный массив (array), содержащий полные пути ко всем найденным подкаталогам. Если подкаталоги не найдены, возвращается пустой массив.
Примеры использования
Пример 1: Сканирование структуры проекта
Предположим, у нас есть следующая структура каталогов:
/var/www/site/ |- components/ | |- header/ | |- footer/ |- pages/ |- _cache/
Вызов функции:
$allSubdirectories = getSubDirs('/var/www/site/');
// $allSubdirectories будет содержать:
// [
// '/var/www/site/components',
// '/var/www/site/components/header',
// '/var/www/site/components/footer',
// '/var/www/site/pages',
// '/var/www/site/_cache',
// ]
pr($allSubdirectories);
Пример 2: Исключение служебных каталогов
Используя ту же структуру, что и в примере 1, но с флагом $excludeUnderlineDir = true.
$publicSubdirectories = getSubDirs('/var/www/site/', true);
// $publicSubdirectories будет содержать:
// [
// '/var/www/site/components',
// '/var/www/site/components/header',
// '/var/www/site/components/footer',
// '/var/www/site/pages',
// ]
// Каталог '/var/www/site/_cache' будет исключен.
pr($publicSubdirectories);
Примечания
- Рекурсия: Функция является рекурсивной, что позволяет ей обходить деревья каталогов любой глубины.
- Права доступа: Для корректной работы веб-сервер должен иметь права на чтение сканируемых каталогов.
- Источник: https://overcoder.net/q/219961
Функция moveFile
Функция moveFile предназначена для безопасного перемещения файла из одного места в другое. Она автоматически создает целевую директорию, если та отсутствует. Ключевой особенностью является обработка ситуации, когда целевой файл уже существует: в этом случае исходный файл просто удаляется, что делает операцию идемпотентной и безопасной для повторного выполнения (например, после сбоя).
Сигнатура
function moveFile(string $old, string $new): void
Аргументы
- string
$old - Полный путь к исходному файлу.
- string
$new - Полный путь к целевому файлу, включая его имя.
Результат
Функция ничего не возвращает (void).
Примеры использования
Пример 1: Стандартное перемещение загруженного файла
Это типичный сценарий использования при обработке загрузок файлов.
$tempFile = $_FILES['avatar']['tmp_name']; $destinationFile = UPLOADS_DIR . 'avatars/' . 'user123.jpg'; moveFile($tempFile, $destinationFile);
Пример 2: Создание вложенных директорий
Функция автоматически создаст всю необходимую структуру каталогов.
$source = '/path/to/source/report.pdf'; $destination = '/path/to/archive/2024/12/monthly-report.pdf'; // Если каталоги /path/to/archive/2024/12/ не существуют, они будут созданы. moveFile($source, $destination);
Пример 3: Обработка уже существующего файла (идемпотентность)
Если скрипт по какой-то причине будет выполнен повторно, он не вызовет ошибку, а просто завершит операцию, удалив исходный временный файл.
$tempFile = '/tmp/processing/image.jpg'; $finalFile = '/var/www/gallery/image.jpg'; // Первый запуск: файл перемещается moveFile($tempFile, $finalFile); // Второй запуск (например, после сбоя и повторной попытки): // функция обнаружит, что $finalFile уже существует, и просто удалит $tempFile. moveFile($tempFile, $finalFile);
Примечания
- Права доступа: Для корректной работы веб-сервер должен иметь права на запись в целевую директорию (и на создание вложенных директорий), а также права на удаление исходного файла.
- Подавление ошибок: Удаление исходного файла при наличии целевого происходит с подавлением ошибок (
@unlink), чтобы избежать предупреждений, если файл уже был удален.
Функция requireSafe
Функция requireSafe является оберткой над стандартной инструкцией require, добавляющей два уровня безопасности: проверку на существование файла и обработку ошибок/исключений (Throwable), которые могут возникнуть во время его выполнения. Это позволяет избежать фатальных ошибок и падения всего приложения, выводя вместо этого информативное сообщение.
Сигнатура
function requireSafe(string $_file): void
Аргументы
- string
$_file - Полный путь к PHP-файлу, который необходимо подключить и выполнить.
Результат
Функция ничего не возвращает (void). Её результат — это либо выполнение кода из подключенного файла, либо вывод отформатированного сообщения об ошибке.
Примеры использования
Пример 1: Безопасное подключение компонентов шаблона
В системе шаблонов часто требуется подключать множество файлов. Использование requireSafe гарантирует, что ошибка в одном из них (например, синтаксическая) не остановит рендеринг всей страницы.
// В основном файле шаблона requireSafe(TEMPLATE_DIR . 'header.php'); requireSafe(TEMPLATE_DIR . 'sidebar.php'); requireSafe(TEMPLATE_DIR . 'main-content.php'); requireSafe(TEMPLATE_DIR . 'footer.php');
Пример 2: Демонстрация обработки ошибки
Предположим, в файле broken-module.php есть ошибка.
// Содержимое файла /path/to/broken-module.php <?php echo $undefinedVariable; // вызовет ошибку ?>
Вызов в основном коде:
echo 'Начало выполнения.';
requireSafe('/path/to/broken-module.php');
echo 'Выполнение продолжается.';
Результат на странице будет примерно таким:
Начало выполнения.
<div class="bg-red800 t-white pad10 t90">
Error in <b>/path/to/broken-module.php</b><br>
Type: <b>Error</b><br>
Message: <b>Undefined variable $undefinedVariable</b><br>
File: <b>/path/to/broken-module.php</b><br>
Line: <b>2</b>
</div>
Выполнение продолжается.
Примечания
- Throwable: Использование
catch (Throwable $e)позволяет перехватывать как традиционные исключения (Exception), так и фатальные ошибки (Error), что делает обработку более надежной.