Как проверить существование папки в PHP: is_dir, file_exists или оба?
Всем привет! Я новичок в PHP и пишу скрипт для загрузки файлов на сервер. Мне нужно проверять, существует ли директория, куда я буду сохранять файлы. Если её нет — создавать.
Я наткнулся на две функции: is_dir() и file_exists(). И теперь не понимаю, какую из них использовать. Вот мой код:
$path = '/uploads/images/';
// Вариант 1
if (is_dir($path)) {
echo "Папка существует";
} else {
mkdir($path, 0777, true);
}
// Вариант 2
if (file_exists($path)) {
echo "Папка существует";
} else {
mkdir($path, 0777, true);
}
Оба варианта вроде работают, но я заметил странное поведение. Если указать путь к файлу, а не к папке, file_exists() возвращает true, а is_dir() — false. Это сбивает с толку.
Ещё я читал, что file_exists() кеширует результаты, и это может привести к ошибкам. А is_dir() — нет. Но я не уверен.
Подскажите, как правильно проверять существование именно директории? Нужно ли использовать обе функции вместе? Или достаточно одной? И что делать с кешированием?
Заранее спасибо за помощь!
<<Используйте is_dir() — это правильный и надёжный способ
Для проверки существования именно директории (папки) в PHP используйте функцию is_dir(). Она возвращает true только если переданный путь является существующей директорией. file_exists() же возвращает true для любого существующего элемента файловой системы — будь то файл, директория или символическая ссылка.
Почему file_exists() не подходит?
Представьте ситуацию: у вас есть файл /uploads/images.txt, а вы проверяете file_exists('/uploads/images/'). PHP может вернуть true из-за особенностей работы с путями (например, если включены магические кавычки или есть символическая ссылка). Это приведёт к тому, что вы не создадите директорию, а потом попытаетесь записать в неё файл — получите ошибку.
Надо ли использовать обе функции?
Нет, не надо. is_dir() полностью решает задачу. Однако есть один важный нюанс — кеширование результатов. PHP кеширует результаты вызовов функций file_exists(), is_dir(), is_file() и других для повышения производительности. Если в процессе выполнения скрипта вы создаёте или удаляете директорию, закешированный результат может устареть.
Пример проблемы с кешированием:
// Первая проверка — директории нет
if (!is_dir('/tmp/mydir')) {
mkdir('/tmp/mydir', 0777, true);
}
// Вторая проверка — PHP может вернуть false,
// потому что закешировал результат первого вызова
if (is_dir('/tmp/mydir')) {
echo "Директория существует"; // Этот код может не выполниться!
}
Решение проблемы с кешированием
Используйте функцию clearstatcache() перед повторной проверкой:
// Создаём директорию
if (!is_dir('/tmp/mydir')) {
mkdir('/tmp/mydir', 0777, true);
}
// Очищаем кеш
clearstatcache();
// Теперь проверка будет точной
if (is_dir('/tmp/mydir')) {
echo "Директория успешно создана";
}
Рекомендуемый паттерн для проверки и создания директории
$path = '/uploads/images/';
// Проверяем существование директории
if (!is_dir($path)) {
// Создаём рекурсивно (создаст все родительские папки)
if (mkdir($path, 0755, true)) {
echo "Директория создана: $path";
} else {
echo "Ошибка создания директории";
}
} else {
echo "Директория уже существует";
}
// Если дальше планируете работать с файлами — очистите кеш
clearstatcache();
Дополнительные советы
- Права доступа: используйте
0755для директорий (владелец может всё, остальные — читать и выполнять).0777— слишком опасно. - Рекурсивное создание: третий параметр
trueвmkdir()создаёт все промежуточные директории, если их нет. - Проверка после создания: всегда проверяйте результат
mkdir()— он возвращаетfalseпри ошибке. - Безопасность: никогда не доверяйте пользовательскому вводу для путей. Используйте
basename()или белые списки.
Итог
Используйте только is_dir() для проверки существования директории. file_exists() здесь не нужен. Если в скрипте несколько раз проверяется один и тот же путь, а между проверками происходят изменения — используйте clearstatcache().
Альтернативный подход: проверка через file_exists + is_dir
Хотя is_dir() — основной инструмент, некоторые разработчики используют комбинацию для надёжности:
$path = '/uploads/images/';
if (file_exists($path) && is_dir($path)) {
echo "Директория существует";
} else {
mkdir($path, 0755, true);
}
Такой код явно проверяет, что путь существует и является директорией. Это избыточно, но может быть полезно в легаси-коде или при работе с символическими ссылками.
Когда это может пригодиться?
- Если вы ожидаете, что по пути может быть файл, а не папка, и хотите явно обработать эту ситуацию.
- При отладке — чтобы точно знать, что вернула каждая функция.
Но помните:
Этот подход не решает проблему кеширования. Если вы создали директорию между вызовами file_exists() и is_dir(), результат может быть некорректным. В современных проектах лучше использовать только is_dir() с clearstatcache() при необходимости.
Ещё один вариант — использовать is_dir() с проверкой на ошибки через @ (подавление ошибок), но это считается плохой практикой.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Асинхронное программирование в Kotlin: полное руководство