марта
22
2010

Заметки о PHP: восьмеричные числа и права доступа

Быть может странно, но, несмотря на свою полезность, неявное преобразование типов в PHP подставило мне подножку при разработке скрипта. Ситуация проста – мне было необходимо написать скрипт, который забирал настройки из таблицы БД MySQL – права и нужную директорию – и создавал в ней вложенную директорию с заданными правами, а также менять права доступа на существующие файлы. Права хранятся в виде числа – 777, например (полный доступ к директории для всех пользователей в UNIX-like системах). Если я задам число в коде как восьмеричное, то все будет в порядке (Я опустил получение данных из базы, т.к. это принципиально не важно):

$dir="/path/to/dir/";
$createDir="somedir";
$permissions=0775; //так задается число в восьмеричной системе исчисления
mkdir ($dir.$createDir,$permissions);
// или при смене прав
chmod($dir.$createDir,$permissions);

Функции mkdir и chmod в качестве второго параметра – прав доступа – принимают восьмеричное число. И видно, что это работает. Но, только до тех пор, пока нет необходимости получать это число откуда-нибудь еще, а не из переменной в скрипте, тип и система исчисления которой явно заданы. К чему это приводит? Посмотрим:

$dir="/path/to/dir/";
$createDir="somedir";
$permissions=775; //десятичное число
mkdir ($dir.$createDir,$permissions);
// или при смене прав
chmod($dir.$createDir,$permissions);
$dir="/path/to/dir/";
$createDir="somedir";
$permissions="775"; //строка
mkdir ($dir.$createDir,$permissions);
// или при смене прав
chmod($dir.$createDir,$permissions);
Бах! И мы получили кривые права. В описании функции chmod мягонько так написано, что “возможна” ошибка в такой ситуации. Но не объясняется почему. А дело всё в неявном преобразовании типов данных PHP. Когда в функцию передается строковый параметр, он автоматически преобразуется в число (т.к. входной параметр – число). Но при этом почему-то не учитывается, в какой системе счисления это число. И это не смотря на то, что входной праметр прав у chmod и mkdir – восьмеричное число, и об этом указывается в документации. И, конечно же, по первому примеру видно, что PHP умеет работать с восьмеричными числами.
Для преобразования числа восьмеричной системы в PHP есть три функции – decoct (из десятичной в восьмеричную), octdec (из восьмеричной в десятичную) и base_convert (из какой-то в какую-то, например из двоичной в восьмеричную). octdec() возвращает действительное число, а вот две другие – decoct и base_convert – почему-то строку. И вот тут я напарываюсь на интересный момент – эти функции нормально отрабатывают, возвращают восьмеричные значения, но, похоже, что передать параметр с их помощью у меня не получится. А все потому, что возвращают они строковое значение, которое при передаче в функцию будет преобразовано в десятичный int, неправильно обработано функцией, и в результате – кривые права доступа к файлу. Получается, что всё равно придется что-то “хардкодить” – либо права доступа, либо команду UNIX-like систем chmod:
`chmod {$permissions} {$pathToFile}`;
И то, и другое – те еще “костыли”: первый не позволит гибко менять права доступа, второй не будет работать, скажем, в Windows. Благо chmod в Windows вообще эффекта не имеет. Побочный плюс второго варианта в том, что можно использовать синтаксис команды chmod, который весьма мощен и позволяет гибко и просто выставлять права доступа на файлы. Минус второго варианта – в платформозависимости кода и возможных при этом проблемах.

Спасибо вам за ретвит:

...и за добавление статьи в:
Автор: Олег | Категория: php

Комментариев: 2 »

RSS-фид комментариев для этого поста | Трекбек


Оставить комментарий

* Необходимые для заполнения поля
Before you submit form:
Human test by Not Captcha

 

Шаблон: TheBuckmaker.com | Локализация, модификация: Олежек | Хостинг: Bluehost.com