ALBIREO CMS
version: 2026.04.17

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

checkRealFile checkUrlAsRealFile contentFile copyDir copyFile deleteDir dirToArray dirToArrayFlat dirToArrayFlat2 findFile findFilesFromDirs getContentFile getExtension getSafePath 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' => 'textsimple'
]);

// Чтение с защитой кода и обработкой
$codeExample = contentFile('/examples/demo.html', [
    'protect-pre' => true,
    'text-function' => 'htmlspecialchars'
]);

Функция copyDir

Рекурсивное копирование каталогов с сохранением структуры подкаталогов.

Сигнатура

function copyDir(string $src, string $dest): void

Аргументы

string $src
Абсолютный путь к исходному каталогу. Должен существовать и быть доступным для чтения.
string $dest
Абсолютный путь к целевому каталогу. Будет создан (включая все подкаталоги) если не существует.

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

// Простое копирование
copyDir('/var/www/old-site', '/var/www/new-site');

// Копирование с предварительной проверкой
if (file_exists($sourceDir)) {
    copyDir($sourceDir, $backupDir . date('Y-m-d'));
}

Обработка ошибок

  • Генерирует исключение если исходный каталог не существует
  • Может генерировать предупреждения при проблемах с правами доступа
  • Рекомендуется использовать try-catch для обработки ошибок

Функция copyFile

Обеспечивает копирование файла с предварительной проверкой и подготовкой целевой директории. Если папки, в которую должен быть помещен файл, не существует, функция создаст всю иерархию подкаталогов автоматически.

Сигнатура

function copyFile(string $src, string $dest, int $chmodDir = 0777): bool

Аргументы

string $src
Путь к исходному файлу. Если файл не существует, функция вернет false.
string $dest
Целевой путь копирования, включая имя файла.
int $chmodDir
Права доступа, которые будут установлены для создаваемых директорий (в восьмеричном формате, например 0775).

Результат

Логическое значение (bool): true, если файл успешно скопирован, и false, если исходный файл не найден или возникла ошибка при создании папок/копировании.

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

// Пример 1: Копирование в глубоко вложенную структуру
$source = "source_file.zip";
$destination = "archive/yearly/2026/files/backup.zip";

copyFile($source, $destination);

// Пример 2: Использование с пользовательскими правами на папки
copyFile("config.dist", "custom/app/config.php", 0750);

Примечания

Функция использует системный вызов mkdir с параметром recursive: true. Стоит учитывать, что на некоторых конфигурациях сервера текущая umask может влиять на итоговые права создаваемых директорий.

Функция 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 = [], string $keyRoot = '')

Аргументы

string $dir
Абсолютный путь к сканируемому каталогу
array $allowExt
Массив разрешенных расширений файлов (например ['php', 'jpg']). Пустой массив - без фильтрации.
string $keyRoot
Имя ключа для файлов корне основного каталога, например / или ::root::. По умолчанию пусто — файлы попадают в основной массив без группировки.

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

Ассоциативный массив (array), где:

  • Ключи - имена подкаталогов
  • Значения - массивы содержимого подкаталогов
  • Файлы - элементы массива

Формат результата

Пример возвращаемого массива:

[
    'subdir1' => [
        'file1.txt',
        'file2.php',
        'nested' => [
            'image.jpg'
        ]
    ],
    'file3.html'
]

// или если указать $keyRoot = ':root'
[
    'subdir1' => [
        'file1.txt',
        'file2.php',
        'nested' => [
            'image.jpg'
        ]
    ],
    
    ':root' => [
        '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

Предназначена для поиска файла в нескольких возможных местах расположения. Это полезно для реализации системы переопределения файлов (overriding), поиска конфигураций или автоматического определения путей к ресурсам (assets).

Сигнатура

function findFile(string $file, array $dirs, array $returnDirs = []): string|false

Аргументы

string $file
Имя искомого файла или его относительный путь (например, 'subdir/file.php').
array $dirs
Список директорий, которые будут проверены по порядку. Должны быть указаны полные пути.
array $returnDirs
Массив строк для замены. Если файл найден в папке с индексом N из массива $dirs, функция попытается вернуть значение из $returnDirs с тем же индексом N. Если индекс отсутствует или массив пуст, вернется полный путь к файлу.

Результат

Возвращает string с путем к файлу или сформированным значением из $returnDirs. Если файл не найден ни в одной из директорий, возвращается false.

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

// 1. Поиск системного файла
$path = findFile('settings.json', ['/app/config', '/etc/myapp']);
if ($path) {
    $settings = json_decode(file_get_contents($path));
}

// 2. Определение URL для CSS-файла с приоритетом в теме пользователя
$file = 'style.css';
$cssUrl = findFile(
    $file,
    [
        '/var/www/public/user_theme/css', 
        '/var/www/public/default_theme/css'
    ],
    [
        '/themes/user/css', 
        '/themes/default/css'
    ]
);

if ($cssUrl) {
    echo '<link rel="stylesheet" href="' . $cssUrl . '">';
}

Примечания

  • Функция использует внутреннюю функцию checkRealFile() для фактической проверки наличия файла.
  • При использовании $returnDirs, функция автоматически обрабатывает разделители строк, удаляя лишние слэши в конце префикса перед добавлением имени файла.
  • Поиск прекращается после первого найденного совпадения.

Функция findFilesFromDirs

Собирает уникальные файлы из набора директорий по заданному шаблону. Если в нескольких директориях присутствуют файлы с одинаковыми именами, приоритет отдается файлу из директории, переданной последней в аргументах.

Сигнатура

function findFilesFromDirs(string $pattern, string ...$directories): array

Аргументы

string $pattern
Шаблон поиска (маска), соответствующий правилам функции glob().
string ...$directories
Переменное количество путей к директориям, которые необходимо просканировать.

Результат

Возвращает array — список полных путей к найденным файлам, отсортированных по имени с использованием алгоритма естественной сортировки (natsort).

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

// Поиск PHP-файлов в папках с перекрытием имен
$files = findFilesFromDirs('*.php', 'src/base', 'src/custom');


// Результат: 
// [
//     '/full/path/to/src/custom/config.php',
//     '/full/path/to/src/base/utils.php'
// ]
// Если config.php был в обоих, в результат попал файл из src/custom

Примечания

  • Функция использует glob() для поиска файлов, поэтому поведение зависит от ограничений этой функции в вашей ОС.
  • Естественная сортировка (natsort) полезна, если имена файлов содержат числа (например, file2.php будет идти раньше file10.php).
  • Директории обрабатываются последовательно слева направо: последние найденные файлы перезаписывают предыдущие в массиве результатов.

Функция 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']);
});

Особенности

  • Всегда возвращает расширение в нижнем регистре
  • Работает с файлами, имеющими несколько точек в имени
  • Для файлов без расширения вернет пустую строку
  • Чувствительна к регистру при проверке разрешенных расширений

Функция getSafePath

Выполняет фильтрацию и нормализацию строкового пути, предотвращая атаки типа "Path Traversal" и удаляя некорректные сегменты и символы.

Сигнатура

function getSafePath(string $path, string $sep = '/'): string

Аргументы

string $path
Входная строка, содержащая путь к файлу или директории.
string $sep
Символ-разделитель, который будет использован для сборки результирующей строки. По умолчанию используется прямой слеш /. Можно использовать DIRECTORY_SEPARATOR.

Результат

Возвращает очищенную строку (string), состоящую только из валидных имен директорий и файлов, разделенных указанным символом.

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

// проверка на недопустимые пути
if ($dir !== getSafePath($dir)) return 'Неверный url путь';

if ($dir !== getSafePath($dir, DIRECTORY_SEPARATOR)) return 'Неверный путь на сервере';


// подчистка входящего адреса
$address = getSafePath($address);

// заменить «опасные» символы
$address = strToSlug($address, deleteDot: true, deleteSlash: false);

См. также isPathTraversal()

Функция 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 $src, string $dest)

Аргументы

string $src
Полный путь к исходному файлу.
string $dest
Полный путь к целевому файлу, включая его имя.

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

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