‹
| КрасносельскийКонстантинКонстантинович |
ТаблицейБлоками.PHP chmod – установка и чтение прав доступа в Unix системах с помощью PHP |
Последняя модификация: 10.08.2014 г
Страница загружена с адреса: http://webdesign.site3k.ru/consulting/php_chmod.html
Функция chmod языка PHP может вызвать неожиданное затруднение. Понятный и простой, на первый взгляд, синтаксис:
chmod(filename, attrib);
в котором filename определяет имя файла или каталога, для которого трубуется изменить атрибут (режим доступа), а attrib – режим, который требуется установить, имеет ряд скрытых особенностей.
Первой из них, является, конечно же, сетевая система прав доступа, утанавливающая отдельно права для владельца файла, группы, к которой он относится и всех остальных пользователей. Права, обычно представляются строками:
drwxr-x--x -rw-r--r--
Первый символ описывает тип элемента: дефис "-" означает файл, символ "d" означает каталог. Дальнейшие девять символов описывают права доступа:
r – read право на чтение w – write право на запись x – execute право на выполнение*
*право на выполнение для каталога означает возможность просмотреть его содержимое (войти в каталог).
Первые три символа из девяти устанавливают права доступа для владельца, вторые три - для группы, третьи - для всех пользователей. Каждый набор символов r, w, x показывает текущие установленные права доступа для каждой категории пользователей. Если вместо символа стоит дефис, то соответствующее право отсутствует.
Однако, PHP команда chmod не признает указание прав доступа в виде текстовой строки. Права доступа для нее обятельно должны указываться в виде числа от 0 до 7, для каждого типа пользователей. Чтобы понять, как преобразовываются числовые значения в текстовые и, наоборот, полезно представить текстовыу строку в виде битовой маски для однозначности которой необходимо строгое соблюдение порядка атрибутов: 1 группа цифр относится к владельцу файла, вторая к его группе, третья – к остальным пользоватлям. Кроме того, необходимо соблюдать последовательность прав: 1 право чтения, 2 – право записи, 3 – право выполнения.
При соблюдении этих условий, приведенные выше строки
drwxr-x--x -rw-r--r--
Можно представить как набор двоичных данных:
100.0.111.101.001 1.0.0.110.100.100
(Это фактический набор атрибутов, с точки зрения PHP команды chmod важны лиш последние три набора в каждой строке).
Единица в последних трех группах каждой строки означает наличие права (истину), ноль – его отсутствие (ложь).
Преобразование данного представления в десятиричный формат дает более привычное числовое представление:
| Двоичное | Десятичное | Физический смысл значения |
|---|---|---|
| 000 | 0 | ничего не разрешает (только удалять) |
| 001 | 1 | доступ на выполнение (x) |
| 010 | 2 | доступ на запись (w) |
| 100 | 4 | доступ на чтение (r) |
Побитовое сложение (сдвиг) значений прав для каждой группы пользователей позволяет сократить десятиричную запись до одного числа в каждой группе:
| Двоичное сложение | Десятичнное сложение | Физический смысл |
|---|---|---|
| 001+010=011 | 1+2=3 | доступ на выполнение и запись (-wx) |
| 001+100=101 | 1+4=5 | доступ на выполнение и чтение (r-x) |
| 010+100=110 | 2+4=6 | доступ на чтение и запись (rw-) |
| 001+010+100=111 | 1+2+4=7 | доступ на чтение, запись и выполнение (rwx) |
Таким образом маска атрибутов для вышеуказаного примера (показаны только последние три группы, имеющие значение для прав доступа):
В текстовом формате имеет вид:
rwx.r-x.--x rw-.r--.r--
В двоичном:
111.101.001 110.100.100
А в десячичном, приобретает вид:
7.5.1 6.4.4
Именно в таком виде, только без разделяющих точек, и принимает PHP команда chmod значение атрибутов, корорые следует установить.
Но, и это не все! Нельзя просто вписать в PHP-скрипт команду
chmod('myscript.php', 755);
Чтобы сделать файл myscript.php выполняемым: Команда chmod принимает значение прав только в 8-ричном формате! Ну что тут поделаеш – разработчики PHP специально усложняли нам жизнь, чтобы наши мозги не атрофировались. ☺
Чтобы команда chmod нормально выполнялась, ей нужно указать преобразование в 8-ричный формат, поставив перед значением прав ноль:
chmod('myscript.php', 0755);
Вы думаете это все?
Позвольте! Зачем так упрощать себе жизнь? Разработчики PHP позаботились о том, чтобы эта статья не закончилась так просто.
Добавление ноля перед атрибутами хорошо действует, когда вы заранее знаете, какой нужен атрибут. А если нужно сделать так, чтобы права выставлялись формой на HTML-странице? К примеру, вы хотите создать систему управления файлами?
Допустим, из формы приходит переменная $attrib, содержащая значение прав доступа, типа 755. Вы думаете что, приклеете к ним ноль:
chmod('myscript.php', '0'.$attrib);
и, все у вас получится?
Ага, размечтались. Разработчики PHP не позаботились об автоматическом преобразовании десятичного числа в восмиричное, будут они вам строки преобразовывать?
Нет, конечно. Самим придется потрудиться:
chmod('myscript.php',octdec($attrib));
вставляя функцию octdec преобразования числа (или строки, имеющей числовае значение) в восьмиричный формат. Или используя функцию eval:
eval("chmod('myscript.php',0$attrib);");
Да, теперь все заработает. Но только на запись! Попробуйте считать атрибуты функией fileperms и не опплеваться: она вернет все в том же восьмиричном формате! Лично я теряюсь в интерпритации таких значений. Для нормального восприятия, их приходтся предварительно преобразовывать функцией decoct в десятиричный формат, а затем, из полученного результата брать последние 3 символа:
substr(
decoct(fileperms('myscript.php')),
strlen(decoct(fileperms('myscript.php')))-3,
strlen(decoct(fileperms('myscript.php')))
);
Только так можно получить нормальные числовые атрибуты.
$perms=decoct(fileperms('myscript.php'));
$len=strlen($perms);
if ($len==5){ // вместо длины можно использовать is_dir() и другие методы
$attrib='d';// каталог
}else{
$attrib='-';// файл
}
// 1 метод: Вычисление через двоичное преобразование
for($i=$len-3; $i < $len; $i++){
@$attrib2=decbin(substr($perms,$i,1));
if (substr($attrib2,0,1)==1){
$attrib.='r';
}else{
$attrib.='-';
}
if (substr($attrib2,1,1)==1){
$attrib.='w';
}else{
$attrib.='-';
}
if (substr($attrib2,2,1)==1){
$attrib.='x';
}else{
$attrib.='-';
}
}
// 2 метод: Прямое вычисление (закомментирован)
//for($i=$len-3; $i < $len; $i++){
// switch (substr($perms,$i,1)) {
// case 0:
// $attrib.='---';
// break;
// case 1:
// $attrib.='--x';
// break;
// case 2:
// $attrib.='-w-';
// break;
// case 3:
// $attrib.='-wx';
// break;
// case 4:
// $attrib.='r--';
// break;
// case 5:
// $attrib.='r-x';
// break;
// case 6:
// $attrib.='rw-';
// break;
// case 7:
// $attrib.='rwx';
// break;
// }
//}
Но числовой формат во многих случаях окажется удобней буквенного (сравните 755 и -rwxr-xr-x, что быстрее понимается?).
Вот теперь на языке PHP можно создавать файловые менеджеры и системы управления файлами (однако изменить атрибуты в файлах, загруженых по ftp, может не позволить сервер из-за принадлежности к разным группам).
< Предыдущая (Экспорт и импорт) PHP chmod Следующая (Web 2.0)>
