is_writable()
PHP is_writable() возвращает true, если файл или каталог доступен для записи. Синтаксис, особенности и кеш stat.
Функция PHP is_writable() позволяет узнать до попытки записи, разрешено ли текущему процессу записывать в указанный файл или каталог. На этой странице рассматриваются её синтаксис, возвращаемое значение, поведение кеширования и практические паттерны безопасного использования.
Что такое функция is_writable()?
is_writable() — это встроенная функция PHP, которая возвращает true, если указанный файл (или каталог) существует и доступен для записи пользователю, от имени которого работает процесс PHP, и false в противном случае. Функция принимает один аргумент и не выполняет запись — она только проверяет права доступа.
Проверка основана на эффективном идентификаторе пользователя запущенного процесса (например, www-data под Apache/Nginx-FPM), а не на пользователе, которому принадлежит скрипт. Файл, который вы можете редактировать в своём редакторе, может по-прежнему сообщаться как недоступный для записи веб-сервером.
У is_writable() есть псевдоним — is_writeable() (с дополнительной буквой e); они идентичны.
Синтаксис
is_writable(string $filename): bool| Параметр | Описание |
|---|---|
$filename | Путь к файлу или каталогу для проверки. Может быть указан относительно текущего рабочего каталога. |
Возвращает true в случае успеха, false если путь недоступен для записи или не существует.
Как использовать функцию is_writable()
Типичный паттерн — «смотри перед прыжком»: убедиться, что файл доступен для записи, прежде чем пытаться открыть его на запись, чтобы при необходимости завершить работу с понятным сообщением, а не с предупреждением во время выполнения.
Поскольку песочница runner создаёт data.txt, приведённый выше пример выводит The file 'data.txt' is writable.
Полный рабочий пример
Этот самодостаточный скрипт создаёт файл, проверяет его и записывает данные только при успешной проверке:
<?php
$file = 'log.txt';
// Create the file so the example is reproducible.
file_put_contents($file, "first line\n");
if (is_writable($file)) {
file_put_contents($file, "second line\n", FILE_APPEND);
echo "Wrote to $file:\n";
echo file_get_contents($file);
} else {
echo "Cannot write to $file.";
}Вывод:
Wrote to log.txt:
first line
second lineПроверка каталога
is_writable() работает и с каталогами. Это правильная проверка перед созданием нового файла: вы не можете проверить файл (он ещё не существует), поэтому проверяете папку, в которой он будет создан.
<?php
$dir = __DIR__; // the directory this script lives in
if (is_writable($dir)) {
echo "New files can be created in: $dir";
} else {
echo "Directory is read-only: $dir";
}Распространённые ловушки
- Функция не бросает исключений — она выдаёт предупреждения. Если
$filenameнедействителен таким образом, который PHP не может разрешить (например, нарушение ограничения open_basedir), PHP может выдатьE_WARNING. Возвращаемое значение по-прежнему равноfalse. Подавляйте с помощью@только в крайнем случае. - Результаты могут быть закешированы. PHP ведёт stat-кеш. Если права доступа к файлу изменятся в ходе выполнения того же скрипта,
is_writable()может вернуть устаревший результат. Вызывайтеclearstatcache()перед повторной проверкой, чтобы принудить PHP заново прочитать файловую систему. falseнеоднозначно. Результатfalseозначает «недоступен для записи или не существует». Если вам нужно различить эти случаи, используйте его в сочетании сfile_exists().- Состояние гонки TOCTOU. Между проверкой
is_writable()и фактической записью права доступа к файлу могут измениться. В критически важном коде не полагайтесь только на проверку — обрабатывайте также ошибку самой операции записи.
Если вы изменили права доступа в середине скрипта и повторно проверяете, сначала очистите кеш:
<?php
$file = 'config.ini';
file_put_contents($file, "data\n");
var_dump(is_writable($file)); // bool(true)
chmod($file, 0444); // make it read-only
clearstatcache(); // force PHP to re-read the filesystem
var_dump(is_writable($file)); // bool(false)Вывод:
bool(true)
bool(false)Связанные функции
is_readable()— аналог для проверки прав на чтение.file_exists()— проверить существование без проверки прав доступа.is_file()— убедиться, что путь является обычным файлом.fopen()/fwrite()— открыть и записать в файлы после успешной проверки.chmod()— изменить биты разрешений файла.
Заключение
is_writable() позволяет скрипту заранее подтвердить право на запись и завершить работу корректно, не вызывая предупреждений во время выполнения. Помните о трёх особенностях: она отражает права пользователя процесса, false также означает «не существует», а её результаты кешируются до вызова clearstatcache(). Сочетайте её с обработкой ошибок самой операции записи для надёжного кода работы с файлами.