Управление папками в среде PHP: функции, итераторы и примеры

Раздел: Программирование на PHP -> Работа с файловой системой

Основные подходы к работе с папками в PHP

Наиболее эффективный способ создания и управления папками в PHP - это использование комбинации функций mkdir(), is_dir() и chmod() с обязательной проверкой ошибок. Такой подход гарантирует безопасное взаимодействие с файловой системой и предотвращает неожиданные сбои.


$dir = '/path/to/new/folder';
if (!is_dir($dir)) {
    if (mkdir($dir, 0755, true)) {
        echo 'Папка создана';
    } else {
        echo 'Ошибка создания';
    }
} else {
    echo 'Папка уже существует';
}

В этом примере mkdir() с флагом true рекурсивно создаёт все недостающие родительские директории, а is_dir() предотвращает попытку повторного создания.

Типичные ошибки:

  • Недостаточные права доступа - используйте chmod() после создания.
  • Игнорирование возвращаемого значения mkdir() - всегда проверяйте результат.
  • Передача неверного пути с пробелами или специальными символами - применяйте realpath() или проверку через dirname().

Как проверить существование папки и получить её содержимое?

Для проверки используется is_dir(), для чтения списка файлов - scandir().


$path = './uploads';
if (is_dir($path)) {
    $files = scandir($path);
    // исключаем '.' и '..'
    $files = array_diff($files, array('.', '..'));
    foreach ($files as $file) {
        echo $file . '\n';
    }
} else {
    echo 'Директория не найдена';
}

Если папка содержит большое количество элементов, scandir() может потреблять много памяти. В таких случаях используйте итераторы (см. раздел расширенных примеров).

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

Функция rmdir() удаляет только пустые директории. Для непустых требуется рекурсивное удаление.


$dir = './temp';
if (is_dir($dir)) {
    if (rmdir($dir)) {
        echo 'Папка удалена';
    } else {
        echo 'Ошибка удаления (возможно, папка не пуста)';
    }
} else {
    echo 'Папка не существует';
}

Распространённая ошибка - попытка удалить непустую папку без предварительной очистки. Всегда проверяйте содержимое или используйте рекурсивное удаление.

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

Для этих операций применяется rename(), которая работает как с файлами, так и с директориями.


$old = './old_folder';
$new = './new_folder';
if (is_dir($old)) {
    if (rename($old, $new)) {
        echo 'Папка переименована/перемещена';
    } else {
        echo 'Ошибка: возможно, целевая папка уже существует или нет прав';
    }
} else {
    echo 'Исходная папка не найдена';
}

Если целевая папка уже существует, rename() вернёт false. Перемещение между разными файловыми системами может не поддерживаться.

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

Используется chmod(). Права задаются в восьмеричном формате.


$dir = './secured';
if (is_dir($dir)) {
    if (chmod($dir, 0700)) {
        echo 'Права изменены на 0700 (только владелец)';
    } else {
        echo 'Ошибка изменения прав';
    }
} else {
    echo 'Папка не найдена';
}

Неправильные права (например, 0777) могут создать уязвимость. Также chmod() может не сработать, если PHP работает не от владельца папки.

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

Ниже приведены более сложные сценарии, демонстрирующие рекурсивные операции, использование SPL-итераторов и обработку ошибок.

Рекурсивное создание папок с проверкой прав

Пример

function createFolderRecursive($path, $mode = 0755) {
    if (is_dir($path)) {
        return true;
    }
    $parent = dirname($path);
    if (!createFolderRecursive($parent, $mode)) {
        return false;
    }
    if (!mkdir($path, $mode)) {
        return false;
    }
    // устанавливаем права для только что созданной папки
    chmod($path, $mode);
    return true;
}

if (createFolderRecursive('/tmp/a/b/c')) {
    echo 'Папка создана рекурсивно';
} else {
    echo 'Ошибка';
}
Результат: Папка создана рекурсивно (если права позволяют)

Рекурсивное удаление непустой папки

Пример

function deleteFolderRecursive($dir) {
    if (!is_dir($dir)) {
        return false;
    }
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item == '.' || $item == '..') continue;
        $fullPath = $dir . DIRECTORY_SEPARATOR . $item;
        if (is_dir($fullPath)) {
            deleteFolderRecursive($fullPath);
        } else {
            unlink($fullPath);
        }
    }
    return rmdir($dir);
}

if (deleteFolderRecursive('./temp_cache')) {
    echo 'Папка и её содержимое удалены';
} else {
    echo 'Ошибка удаления';
}
Результат: Папка и её содержимое удалены

Обход папки с помощью DirectoryIterator

Пример

$path = './documents';
if (is_dir($path)) {
    $iterator = new DirectoryIterator($path);
    foreach ($iterator as $fileInfo) {
        if ($fileInfo->isDot()) continue;
        echo $fileInfo->getFilename() . ' - ' . ($fileInfo->isDir() ? 'папка' : 'файл') . ' - ' . $fileInfo->getSize() . ' байт\n';
    }
} else {
    echo 'Папка не найдена';
}
Пример вывода:
readme.txt - файл - 1234 байт
images - папка - 4096 байт

Использование RecursiveDirectoryIterator для глубокого обхода

Пример

$path = './project';
if (is_dir($path)) {
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    foreach ($iterator as $fileInfo) {
        echo $fileInfo->getPathname() . '\n';
    }
} else {
    echo 'Папка не найдена';
}
Пример вывода:
./project/src/index.php
./project/src/utils/helper.php
./project/config.json

Копирование папки с содержимым

Пример

function copyFolder($source, $dest) {
    if (!is_dir($source)) {
        return false;
    }
    if (!is_dir($dest)) {
        mkdir($dest, 0755, true);
    }
    $iterator = new DirectoryIterator($source);
    foreach ($iterator as $fileInfo) {
        if ($fileInfo->isDot()) continue;
        $srcPath = $fileInfo->getPathname();
        $destPath = $dest . DIRECTORY_SEPARATOR . $fileInfo->getFilename();
        if ($fileInfo->isDir()) {
            copyFolder($srcPath, $destPath);
        } else {
            copy($srcPath, $destPath);
        }
    }
    return true;
}

if (copyFolder('./backup', './archive')) {
    echo 'Папка скопирована';
} else {
    echo 'Ошибка копирования';
}
Результат: Папка скопирована

Получение размера папки (рекурсивно)

Пример

function folderSize($dir) {
    $size = 0;
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    foreach ($iterator as $fileInfo) {
        $size += $fileInfo->getSize();
    }
    return $size;
}

echo 'Размер папки: ' . folderSize('./data') . ' байт';
Результат: Размер папки: 245678 байт

Папка файла PHP - comments

En
Php папка файла (php)