ALBIREO CMS
version: 2025.11.01

Функции файлов Albireo CMS

checkRealFile checkUrlAsRealFile contentFile copyDir deleteDir dirToArray dirToArrayFlat dirToArrayFlat2 findFile getContentFile getExtension getSubDirs moveFile requireSafe

Функция checkRealFile

Функция для безопасной проверки существования файла и корректности пути.

Сигнатура

function checkRealFile(string $dir, string $file): string|false

Аргументы

string $dir
Базовый каталог (должен быть абсолютным путем)
string $file
Имя файла или относительный путь внутри каталога

Возвращаемое значение

Абсолютный путь к файлу (string) или false если:

  • Файл не существует
  • Путь содержит относительные переходы
  • Пути не совпадают после нормализации

Алгоритм работы

  1. Объединяет базовый каталог и путь к файлу
  2. Приводит разделители путей к системному формату
  3. Проверяет существование файла через realpath()
  4. Сравнивает реальный путь с ожидаемым

Примеры использования

// Проверка файла в 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

Алгоритм работы

  1. Проверяет что URL начинается с http:// или https:// + FRONT_URL_NAME
  2. Заменяет домен на BASE_DIR для получения файлового пути
  3. Проверяет существование файла через realpath()
  4. Убеждается что путь находится внутри BASE_DIR
  5. Для каталогов добавляет 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).

Алгоритм работы

  1. Читает содержимое файла через getContentFile()
  2. Передает содержимое и настройки в processingContent()
  3. Возвращает обработанный результат

Примеры использования

// Чтение шаблона без обработки
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), что делает обработку более надежной.