Is writeable: примеры (PHP)
is_writeable(string $filename): boolФункция 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)- 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 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)
Это изменение делает поведение функции более предсказуемым для сценариев создания новых файлов.
// Проверка списка файлов и директорий перед массовой операцией
$paths = ['file1.txt', 'dir1/', 'file2.log'];
$writablePaths = [];
foreach ($paths as $path) {
if (is_writable($path)) {
$writablePaths[] = $path;
}
}
print_r($writablePaths);
// Результат:
// Array
// (
// [0] => dir1/
// )
Результаты is_writable() кэшируются. При многократной проверке одного файла в одном скрипте и возможном изменении прав необходимо очищать кэш.
$file = 'dynamic.txt';
var_dump(is_writable($file)); // Первая проверка
// Предположим, права файла изменились внешним процессом
clearstatcache(true, $file); // Очистка кэша для конкретного файла
var_dump(is_writable($file)); // Актуальная проверка
// Работает не для всех оберток. Для локальных файлов можно использовать file://
$result = is_writable('file:///etc/passwd');
var_dump($result);
// Результат (скорее всего):
// bool(false)
$source = 'data.json';
$backup = 'data.json.bak';
if (is_writable($source) && is_writable(dirname($backup))) {
if (copy($source, $backup)) {
echo "Резервная копия создана.";
}
} else {
echo "Не удалось создать копию: проверьте права доступа.";
}
$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
В 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 поведение похоже, но используется отдельный модуль.