Umask: примеры (PHP)
umask(int mask): intФункция umask в PHP
Функция umask() изменяет текущую маску прав доступа (user file creation mask) для процесса. Эта маска определяет, какие биты прав доступа будут автоматически отключаться при создании новых файлов или директорий функциями вроде fopen(), mkdir() или tempnam().
Функция используется в сценариях, требующих контроля прав доступа к создаваемым файловым объектам. Типичные случаи включают генерацию конфигурационных файлов, работу с временными данными или обеспечение безопасности в многопользовательских средах.
Функция принимает один необязательный параметр:
- $mask (int|null) - Новая маска прав доступа, представленная в виде целого числа. Часто используется восьмеричная запись. Если передано значение null, функция вернет текущую маску без ее изменения. В версиях PHP до 8.0.0 этот параметр был обязательным.
Возвращаемое значение - предыдущее значение маски в виде целого числа.
Базовые примеры использования
Код для определения текущей установленной маски.
$current_mask = umask();
echo "Текущая маска: " . decoct($current_mask) . "\n";Текущая маска: 18
Изменение маски для текущего процесса.
$old_mask = umask(0);
echo "Предыдущая маска: " . decoct($old_mask) . "\n";
echo "Новая маска: " . decoct(umask()) . "\n";Предыдущая маска: 18 Новая маска: 0
Демонстрация влияния маски на права нового файла.
umask(022);
$file = fopen('test.txt', 'w');
fclose($file);
echo 'Права файла: ' . decoct(fileperms('test.txt') & 0777);
unlink('test.txt');Права файла: 644
Аналоги в PHP
Позволяет явно задавать права доступа для уже существующего файла или директории. В отличие от umask(), которая влияет на будущие объекты, chmod() изменяет права уже созданных.
При использовании функций работы с файлами можно задавать конкретные права через контекст потока, что дает точечный контроль без изменения глобальной маски процесса.
umask() предпочтительнее для установки базовых правил на уровне всего скрипта. chmod() или контексты потоков применяются для индивидуальной настройки конкретных объектов.
Распространенные ошибки
Использование десятичного числа вместо восьмеричного приводит к неожиданным правам доступа.
// Ошибка: передача десятичного числа 22 вместо восьмеричного 022
umask(22); // Восьмеричное значение 026
$file = fopen('error.txt', 'w');
fclose($file);
echo decoct(fileperms('error.txt') & 0777); // Результат может быть не 644
unlink('error.txt');640
Установка маски влияет на весь процесс, что может затронуть другие части кода или сторонние библиотеки.
umask(0); // Установка "открытой" маски
// Код сторонней библиотеки создаст файл с правами 666
// ...
umask(022); // Восстановление маски только после всего кодаПотеря предыдущего значения маски осложняет его восстановление.
// Проблемный код
umask(0);
// Создание файлов...
// Как восстановить старое значение?Изменения в версиях PHP
Параметр $mask стал необязательным (nullable). Теперь можно вызвать umask() без аргументов для получения текущей маски, что раньше требовало передачи значения null.
// До PHP 8.0.0
$current = umask(null);
// Начиная с PHP 8.0.0
$current = umask();В PHP 4 и 5 параметр был обязательным. Отсутствие поддержки null могло приводить к предупреждениям.
Расширенные примеры применения
Безопасное изменение маски только для определенного блока кода с гарантированным восстановлением.
function createSecureFile($filename, $content) {
$oldMask = umask(077); // Запретить доступ всем, кроме владельца
$file = fopen($filename, 'w');
fwrite($file, $content);
fclose($file);
umask($oldMask); // Восстановить исходную маску
return $filename;
}
$file = createSecureFile('secret.txt', 'data');
echo 'Права файла: ' . decoct(fileperms('secret.txt') & 0777);
unlink('secret.txt');Права файла: 600
Маска влияет и на создаваемые директории через mkdir().
umask(027); // Группа: чтение-запись, остальные: нет доступа
mkdir('private_dir', 0755); // Фактические права: 0755 & ~027 = 0750
echo 'Права директории: ' . decoct(fileperms('private_dir') & 0777);
rmdir('private_dir');Права директории: 750
Функция для предсказания итоговых прав файла с учетом текущей маски.
function getFinalPermissions($basePermissions) {
$currentMask = umask();
$final = $basePermissions & ~$currentMask;
umask($currentMask); // Не меняем исходную маску
return $final;
}
umask(022);
$base = 0666; // Базовые права для файла
$final = getFinalPermissions($base);
echo 'При маске ' . decoct(umask()) . ' и базовых правах ' . decoct($base) . '\n';
echo 'Фактические права будут: ' . decoct($final);При маске 22 и базовых правах 666 Фактические права будут: 644
Использование разных масок для файлов и директорий в рамках одного процесса.
// Установка общей маски
umask(022);
// Создание директории с одними правами
mkdir('docs', 0755); // Права: 755 & ~022 = 755
// Временное изменение маски для файлов
$old = umask(027);
$file = fopen('docs/internal.txt', 'w');
fclose($file); // Права: 666 & ~027 = 640
umask($old);
echo 'Права директории: ' . decoct(fileperms('docs') & 0777) . '\n';
echo 'Права файла: ' . decoct(fileperms('docs/internal.txt') & 0777);
unlink('docs/internal.txt');
rmdir('docs');Права директории: 755 Права файла: 640
Аналоги в других языках
Работает аналогично, устанавливает маску для текущего процесса.
import os
old_mask = os.umask(0o022)
print(f'Старая маска: {old_mask:03o}')
print(f'Новая маска: {os.umask(old_mask):03o}')Старая маска: 022 Новая маска: 022
Функция в объекте process. Может принимать строковое представление.
const oldMask = process.umask(0o022);
console.log(`Старая маска: 0${oldMask.toString(8)}`);
console.log(`Новая маска: 0${process.umask().toString(8)}`);Старая маска: 022 Новая маска: 022
Встроенная команда оболочки, влияющая на все создаваемые файлы в сессии.
umask 022
touch testfile
ls -l testfile
rm testfile-rw-r--r-- 1 user group 0 Jan 1 12:00 testfile
В PHP функция возвращает предыдущее значение маски, в то время как в Python и Node.js она может возвращать текущую маску при вызове без аргументов.