1

Is writeable: примеры (PHP)

Функция is_writable: проверка доступности файла для записи
Раздел: Работа с файловой системой
is_writeable(string $filename): bool
Основы функции is_writable

Функция is_writable() проверяет, доступен ли файл или директория для записи. Она возвращает true, если файл существует и в него можно записывать данные. Функция учитывает права доступа в файловой системе, а также особенности безопасного режима (до PHP 5.4) и контекста пользователя (например, веб-сервера).

Функция часто используется перед операциями записи в файл, созданием новых файлов или изменением существующих, чтобы избежать ошибок выполнения.

Аргументы функции

Функция принимает один обязательный аргумент:

  • filename (string) – Путь к проверяемому файлу или директории. Может быть абсолютным или относительным.

Возвращаемое значение – булево (true или false).

Базовые примеры использования
// Пример 1: Проверка файла
$file = 'test.txt';
if (is_writable($file)) {
    echo "В файл можно записывать.";
} else {
    echo "Файл недоступен для записи.";
}
// Результат (зависит от прав доступа):
// Файл недоступен для записи.
// Пример 2: Проверка директории
$dir = './uploads';
if (is_writable($dir)) {
    echo "В директорию можно загружать файлы.";
} else {
    echo "Нет прав на запись в директорию.";
}
// Результат (если папка существует и права 0755 от веб-сервера):
// Нет прав на запись в директорию.
// Пример 3: Проверка несуществующего пути
$result = is_writable('non_existent_file.xyz');
var_dump($result);
// Результат:
// bool(false)
Похожие функции в PHP
  • file_exists() – Проверяет существование файла или директории, но не права доступа.
  • is_readable() – Проверяет, доступен ли файл или директория для чтения.
  • fopen() с режимом 'w' или 'a' – Попытка открыть файл для записи. Если файл недоступен, функция вернет false и вызовет предупреждение. Часто используется в связке с @ для подавления ошибки, но is_writable() дает более чистую проверку.
  • touch() – Пытается изменить время модификации файла или создать его. Может использоваться для косвенной проверки возможности записи.

Когда что использовать: is_writable() предпочтительнее для предварительной проверки прав перед операциями записи. file_exists() нужна только для проверки наличия файла. Для комплексной проверки часто используют is_writable() вместе с is_readable().

Типичные ошибки и предостережения

1. Проверка перед операцией записи, но после возможного изменения состояния. Между проверкой is_writable() и записью (например, file_put_contents()) права могут измениться. Рекомендуется обрабатывать ошибки при самой операции записи.

// Ненадежный подход
if (is_writable($file)) {
    // В этот момент права могут быть отозваны
    file_put_contents($file, 'data'); // Может все равно вызвать ошибку
}

2. Игнорирование результата на несуществующий файл. is_writable() возвращает false для несуществующего пути. Нужно дополнительно проверять file_exists(), если важно различать отсутствие файла и отсутствие прав.

$file = 'new_file.txt';
if (!file_exists($file)) {
    echo "Файл не существует.";
} elseif (!is_writable($file)) {
    echo "Файл существует, но недоступен для записи.";
}

3. Проблемы с символическими ссылками. Функция проверяет права конечного файла, на который ведет ссылка, а не самой ссылки.

Изменения в последних версиях PHP

В PHP 8.0.0 функция is_writable() теперь всегда возвращает true для несуществующего файла, если родительская директория доступна для записи. Это изменение связано с логикой проверки возможности создания файла.

// До PHP 8.0.0
$file = 'non_existent.txt';
var_dump(is_writable($file)); // bool(false)

// Начиная с PHP 8.0.0, если текущая директория доступна для записи
var_dump(is_writable($file)); // bool(true)

Это изменение делает поведение функции более предсказуемым для сценариев создания новых файлов.

Расширенные и специальные примеры
Проверка нескольких путей
Пример php
// Проверка списка файлов и директорий перед массовой операцией
$paths = ['file1.txt', 'dir1/', 'file2.log'];
$writablePaths = [];

foreach ($paths as $path) {
    if (is_writable($path)) {
        $writablePaths[] = $path;
    }
}

print_r($writablePaths);
// Результат:
// Array
// (
//     [0] => dir1/
// )
Использование с clearstatcache()

Результаты is_writable() кэшируются. При многократной проверке одного файла в одном скрипте и возможном изменении прав необходимо очищать кэш.

Пример php
$file = 'dynamic.txt';
var_dump(is_writable($file)); // Первая проверка
// Предположим, права файла изменились внешним процессом
clearstatcache(true, $file); // Очистка кэша для конкретного файла
var_dump(is_writable($file)); // Актуальная проверка
Проверка через URL-обертку (для некоторых протоколов)
Пример php
// Работает не для всех оберток. Для локальных файлов можно использовать file://
$result = is_writable('file:///etc/passwd');
var_dump($result);
// Результат (скорее всего):
// bool(false)
Создание резервной копии только при наличии прав на запись
Пример php
$source = 'data.json';
$backup = 'data.json.bak';

if (is_writable($source) && is_writable(dirname($backup))) {
    if (copy($source, $backup)) {
        echo "Резервная копия создана.";
    }
} else {
    echo "Не удалось создать копию: проверьте права доступа.";
}
Логирование в файл с предварительной проверкой директории
Пример php
$logDir = 'logs';
$logFile = $logDir . '/app.log';

// Важнее проверить директорию, так как файла может не существовать
if (!is_writable($logDir) && !is_writable($logFile)) {
    // Попытка исправить права (в безопасной среде)
    chmod($logDir, 0755);
}

// Теперь можно безопасно писать, обрабатывая ошибки записи
if ($handle = fopen($logFile, 'a')) {
    fwrite($handle, date('Y-m-d H:i:s') . " Запись лога\n");
    fclose($handle);
}
Аналоги в других языках программирования

Is writeable в Python

Используется функция os.access() с флагом os.W_OK.

import os
result = os.access('test.txt', os.W_OK)
print(result)  # True или False
// Вывод:
// False
JavaScript (Node.js)

В Node.js используется модуль fs и метод fs.access() с константой fs.constants.W_OK.

const fs = require('fs');
fs.access('test.txt', fs.constants.W_OK, (err) => {
    console.log(err ? 'Нет доступа' : 'Есть доступ');
});
// Вывод (асинхронный):
// Нет доступа

Is writeable в MySQL

Прямого аналога нет. Права на запись файлов определяются правами операционной системы для пользователя, от которого запущен сервер MySQL. Для проверки можно использовать оператор INTO OUTFILE в запросе SELECT, который завершится ошибкой при отсутствии прав.

SELECT * FROM table INTO OUTFILE '/tmp/test.csv';
-- Ошибка, если нет прав:
-- ERROR 1 (HY000): Can't create/write to file '/tmp/test.csv' (Errcode: 13)

Отличия: В PHP функция синхронна и возвращает булево значение. В Node.js проверка асинхронная. В Python поведение похоже, но используется отдельный модуль.

PHP is_writeable function comments

En
Is writeable Alias of is_writable