Манипуляции с директориями: функции PHP для работы с папками

Раздел: Файловая система PHP -> Файловые операции PHP

Основные операции с папками

Цель: Наиболее универсальный и безопасный способ создания папки с проверкой её существования и рекурсивным созданием вложенных директорий.

Функция mkdir с флагом recursive = true позволяет одним вызовом создать цепочку папок. Предварительная проверка is_dir исключает ошибку, если папка уже существует.


$path = '/var/www/uploads/images/2025';
if (!is_dir($path)) {
    mkdir($path, 0755, true);
}
Папка images/2025 создана (если не существовала).

Пояснение: флаг true указывает создавать все недостающие родительские директории. Права доступа 0755 устанавливаются только на последнюю созданную папку.

Типичные ошибки: Забытая проверка is_dir приводит к Warning: mkdir(): File exists. Неправильный путь или недостаточные права вызывают Permission denied. Рекомендуется использовать абсолютные пути или проверять is_writable.

Как создать одну папку без рекурсии?

Цель: Простое создание одной директории, когда родительская уже существует.


$dir = './temp';
if (!is_dir($dir)) {
    mkdir($dir, 0755);
}

Проблема: если родительская папка отсутствует, mkdir выдаст ошибку. Решение - либо заранее создать родителя, либо использовать рекурсивный режим.

Как удалить пустую папку?

Цель: Очистка временных директорий после завершения работы скрипта.


$dir = './cache/temp';
if (is_dir($dir) && count(scandir($dir)) == 2) { // только . и ..
    rmdir($dir);
}
Папка удалена, если она пуста.

Ошибки: rmdir удаляет только пустые директории. При наличии файлов или подпапок возникает Warning: rmdir(): Directory not empty.

Как удалить папку со всем содержимым?

Цель: Полная очистка директории, например, для сброса кэша.


function deleteDir($path) {
    if (!is_dir($path)) return;
    $items = array_diff(scandir($path), ['.', '..']);
    foreach ($items as $item) {
        $itemPath = $path . DIRECTORY_SEPARATOR . $item;
        is_dir($itemPath) ? deleteDir($itemPath) : unlink($itemPath);
    }
    rmdir($path);
}
deleteDir('./cache');

Рекурсивная функция сначала удаляет все файлы и вложенные папки, затем саму корневую директорию.

Проблемы: Символические ссылки могут вести к неожиданному удалению. Для защиты проверяйте is_link и используйте readlink.

Как переименовать или переместить папку?

Цель: Организация файловой структуры, перенос проектов.


$old = './old_name';
$new = './new_name';
if (is_dir($old) && !is_dir($new)) {
    rename($old, $new);
}

Функция rename работает как для файлов, так и для папок. Перемещение в другую директорию - аналогично, указав новый путь.

Ошибки: Если целевая папка уже существует, rename вернёт false (на некоторых системах может перезаписать). Всегда проверяйте существование цели.

Как получить список файлов и подпапок?

Цель: Обход содержимого для анализа или обработки.


$files = array_diff(scandir('/path/to/dir'), ['.', '..']);
print_r($files);
Array
(
    [0] => file1.txt
    [1] => subdir
    [2] => image.png
)

Использование scandir с фильтрацией служебных элементов. Более гибкий вариант - DirectoryIterator.

Проблемы: scandir не сортирует результаты; для больших директорий используйте FilesystemIterator.

Как рекурсивно обойти все подпапки?

Цель: Поиск файлов по маске, подсчёт размеров, архивация.


$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('./data', RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
    echo $file->getPathname() . PHP_EOL;
}

Класс RecursiveDirectoryIterator обходит все вложенные директории. Флаг SKIP_DOTS исключает . и ...

Ошибки: Большие структуры потребляют память; используйте RecursiveIteratorIterator::LEAVES_ONLY для вывода только файлов.

Расширенные примеры работы с папками

1. Рекурсивное копирование директории

Код:

Пример

function copyDir($src, $dst) {
    if (!is_dir($dst)) {
        mkdir($dst, 0755, true);
    }
    $items = new FilesystemIterator($src, FilesystemIterator::SKIP_DOTS);
    foreach ($items as $item) {
        $target = $dst . DIRECTORY_SEPARATOR . $item->getFilename();
        if ($item->isDir()) {
            copyDir($item->getPathname(), $target);
        } else {
            copy($item->getPathname(), $target);
        }
    }
}
copyDir('./template', './backup');
Папка backup создана с полной копией содержимого template.

Пояснение: Функция использует FilesystemIterator для обхода, рекурсивно создаёт поддиректории. Для копирования файлов применяется copy.

2. Обход с фильтрацией по расширению

Код:

Пример

$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator('./docs', RecursiveDirectoryIterator::SKIP_DOTS)
);
$filtered = new RegexIterator($iterator, '/\.php$/i');
foreach ($filtered as $file) {
    echo $file->getPathname() . PHP_EOL;
}
./docs/index.php
./docs/includes/config.php
...

Пояснение: RegexIterator выбирает только файлы, соответствующие регулярному выражению. Подходит для поиска определённых типов файлов.

3. Использование glob для поиска папок по маске

Код:

Пример

$directories = glob('/var/log/*/error*', GLOB_ONLYDIR);
print_r($directories);
Array
(
    [0] => /var/log/apache2/error
    [1] => /var/log/nginx/error
)

Пояснение: glob с флагом GLOB_ONLYDIR возвращает только папки, соответствующие шаблону. Быстрый способ без рекурсии.

4. Определение размера папки рекурсивно

Код:

Пример

function dirSize($path) {
    $size = 0;
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    foreach ($iterator as $file) {
        $size += $file->getSize();
    }
    return $size;
}
echo 'Размер папки: ' . dirSize('./data') . ' байт';
Размер папки: 1234567 байт

Пояснение: Суммируется размер каждого файла. Для больших папок может быть медленным; альтернатива - системная команда du -sb.

5. Создание временной папки с уникальным именем

Код:

Пример

$tmpDir = sys_get_temp_dir() . '/myapp_' . uniqid();
mkdir($tmpDir, 0700);
echo $tmpDir;
register_shutdown_function(function() use ($tmpDir) {
    array_map('unlink', glob($tmpDir . '/*'));
    rmdir($tmpDir);
});
/tmp/myapp_64f3a2b1c0d9e

Пояснение: uniqid генерирует уникальный суффикс. Функция register_shutdown_function гарантирует очистку при завершении скрипта.

6. Работа с символическими ссылками

Код:

Пример

$target = '/var/www/html';
$link = '/home/user/site';
if (!is_link($link)) {
    symlink($target, $link);
}
echo readlink($link);
/var/www/html

Пояснение: symlink создаёт мягкую ссылку. readlink возвращает путь, на который указывает ссылка. При рекурсивном удалении такие ссылки следует обрабатывать отдельно (не удалять по цепочке).

- Php folder (работа с папками в php)

Работа с папками в PHP - comments

En
Php folder (php)