is_writeable()
Функция is_writable() в PHP проверяет, доступен ли файл или директория для записи текущим процессом, и возвращает true или false.
Что делает функция is_writable()
Функция is_writable() — это встроенная функция PHP, которая проверяет, существует ли заданный путь и доступен ли он для записи текущим процессом. Она работает как для файлов, так и для директорий. Функция возвращает true, если путь существует и доступен для записи, и false в противном случае — в том числе когда путь вообще не существует.
На этой странице рассматриваются синтаксис, возвращаемое значение, типичные варианты использования и подводные камни (кэширование, символические ссылки, права суперпользователя и устаревшее написание is_writeable()), которые часто вызывают путаницу.
is_writeable() против is_writable()
is_writeable() (с дополнительной буквой e) — это старый псевдоним функции is_writable(). Он был объявлен устаревшим в PHP 5.0.0 и удалён в PHP 8.0.0: вызов этой функции теперь приводит к фатальной ошибке Error. В современном коде всегда используйте каноническое написание is_writable().
Синтаксис
is_writable(string $filename): bool| Параметр | Описание |
|---|---|
$filename | Путь к файлу или директории для проверки. Может быть относительным (разрешается относительно текущего рабочего каталога) или абсолютным. |
Возвращаемое значение: true, если $filename существует и доступен для записи, иначе false. Несуществующий путь возвращает false, а не вызывает ошибку.
Базовый пример
Функция возвращает булево значение, поэтому её можно напрямую использовать в условии if. В этом примере выводимое сообщение зависит от того, есть ли у процесса, выполняющего скрипт, право на запись в /path/to/file.
Безопасный шаблон записи
Наиболее распространённое применение — защита операции записи, чтобы скрипт завершался корректно вместо краша с предупреждением о правах доступа:
<?php
$logFile = __DIR__ . '/app.log';
if (is_writable($logFile)) {
file_put_contents($logFile, "Started at " . date('c') . "\n", FILE_APPEND);
echo "Log entry written.";
} else {
echo "Cannot write to $logFile — check permissions.";
}Обратите внимание, что is_writable() проверяет существующий путь. Если файл ещё не существует, как правило, лучше проверить директорию, в которой он будет создан, поскольку создание нового файла требует права на запись в родительской директории:
<?php
$target = __DIR__ . '/cache/data.json';
if (is_writable(dirname($target))) {
file_put_contents($target, '{}');
echo "File created.";
} else {
echo "The cache directory is not writable.";
}На что обратить внимание
- Результаты кэшируются. PHP кэширует метаданные файловой системы через stat cache. Если вы меняете права доступа в ходе выполнения скрипта (например, с помощью
chmod()) и повторно проверяете тот же путь, сначала вызовитеclearstatcache(), чтобы получить актуальный результат. - Проверяется владелец процесса, а не ваш логин. Путь, доступный для записи в вашем терминале, может быть недоступен для пользователя веб-сервера (
www-data,nginxи т.д.), который фактически выполняет PHP. - Работа под правами суперпользователя. Суперпользователь может писать почти везде, поэтому
is_writable()может вернутьtrueдаже для файлов с атрибутом «только для чтения». Не полагайтесь на неё как на механизм обеспечения безопасности. - Символические ссылки разыменовываются. Проверка применяется к целевому файлу символической ссылки, а не к самой ссылке.
- Состояния гонки (TOCTOU). Путь может стать недоступным для записи между проверкой и самой операцией записи. Для критически важных операций лучше попытаться выполнить запись и обработать ошибку, а не полагаться только на предварительную проверку.
<?php
chmod('/tmp/example.txt', 0644);
var_dump(is_writable('/tmp/example.txt')); // may show stale value
clearstatcache(); // refresh the stat cache
var_dump(is_writable('/tmp/example.txt')); // now reflects the new permissionsСвязанные функции
is_readable()— проверяет, доступен ли путь для чтения.file_exists()— проверяет только существование пути.is_file()иis_dir()— разграничивают файлы и директории.chmod()— изменяет права доступа к пути.file_put_contents()иfwrite()— операции записи, которые обычно защищают с помощьюis_writable().
Заключение
Функция is_writable() позволяет проверить перед записью, доступен ли файл или директория для записи текущим процессом — при этом для несуществующих путей она возвращает false вместо исключения. Не забывайте проверять родительскую директорию при создании новых файлов, вызывать clearstatcache() после изменения прав доступа в ходе выполнения скрипта, а также использовать каноническое написание, поскольку is_writeable() удалена в PHP 8.