Определение имени владельца файла операционной системы на PHP без использования posix_getpwuid

В языке PHP Id владельца файла системы можно определить используя функцию fileowner, далее зная идентификатор владельца файла можно используя функцию posix_getpwuid($fileOwnerId) получить имя пользователя, например "apache"(без кавычек). При этом важно, на Вашем сервере может быть не установлено необходимое расширение языка PHP и функция posix_getpwuid в таком случаи будет не доступна наряду с функцией posix_getuid о которой будет написано далее. Если Вам тем не менее необходим функционал по определению имени пользователя системы которому принадлежит определённый файл имеет смысл установить расширение языка PHP необходимого для использования функций указанных выше, в случаи с операционной системой CentOs для установки можно выполнить в командной строке команду yum install php-posix, по крайней мере для версии PHP 7.3, на которой в частности тестировался рассматриваемый на этой странице код, такой вариант может подойти.

Тем не менее в моём случаи функционал по определению имени пользователя владельца файла в ОС применялся в частности в web-редакторе файлов который я разрабатываю и были случаи применения редактора на серверах на которых не было установлено PHP-расширение для использования функции posix_getpwuid, что приводило к фатальной ошибке, в этом случаи я например исправлял код редактора, убирая функционал связанный с функцией posix_getpwuid, а так же с функцией posix_getuid которая получает имя пользователя от имени которого запущен PHP-скрипт и которая использовалась до её замены функцией get_current_user, последняя указанная функция так же получает имя пользователя от которого запущен PHP, при этом не требует наличия указанного выше расширения PHP. При правке кода я например заменял функцию posix_getpwuid на пустой массив в результате чего при просмотре содержания дирректорий из моего web-редактора файлов, который так же включает в себя коммандер не было видно имени пользователя которому принадлежит файл или дирректория, что может быть полезным. Другим вариантом для использования моего редактора файлов без замены указанных выше функций является установка указанного выше расширения языка PHP, при этом данный вариант был возможен не в всех случаях, так как у меня к примеру могло не быть необходимых доступов или же возможность установки расширений PHP на сервер было необходимо согласовывать, кроме того возможно что установленное расширение на сервере более ни для чего не пригодится. Для того чтобы редактор файлов работал без привязки к расширению PHP и без ограничения по функционалу я стал искать варианты определения имени владельца файла операционной системы без использования функции posix_getpwuid и без необходимости устанавливать какие либо расширения PHP. Вероятно, что метод о котором далее пойдёт речь не стоит использовать для решения Вашей задачи, а имеет смысл всё же установить необходимое расширение языка PHP и использовать стандартную функцию posix_getpwuid, тем не менее если Вам всё же необходимо наличие функционала по определению владельца файла, а возможности установить расширение языка PHP у Вас нет, то вполне возможно предложенный ниже вариант Вам может подойти.

Изучая варианты получения имени владельца файла я решил что для моей задачи может подойти выполнение в командной строке команды ls с флагом -l за которым следует адрес файла(относительный или абсолютный), адрес можно не указывать в этом случаи информация будет отображена для текущей выбранной дирректории(выбрать дирректорию можно например используя команду cd). Эту команду можно заменить командой ll за которй сразу идёт адрес элемента для которого запрашивается информация, в этом случаи наличие флага не потребуется, тем не менее в скрипте ниже я использую команду ls с флагом -l. В результате выполнения команды программа возвращает строку(если в качестве адреса передан адрес файла) или несколько строк(если в качестве адреса передана дирректория в которонй находится несколько элементов) или же может вернуться пустой результат если в дирректории которая передана команде отсутствуют какие либо элементы(другие дирректории, файлы, ссылки). Каждая строка возвращаемая командой ls -l содержит следующую информацию: 1)права доступа к элементу; 2)тип элемента(например указывается 1 если элемент является файлом, 2 - если дирректория); 3)имя владельца элемента в операционной системе; 4)имя группы операционной системы к которой относится элемент; 5)размер в байтах; 6)месяц изменения файла; 7)число изменения файла; 8)часы и минуты последнего изменения файла разделённые знаком двоеточия без пробелов между ними; 9)адрес и имя элемента или только имя элемента в зависимости какой именно адрес был передан команде ls, например если передан абсолютный адрес файла то в этом случаи выведется абсолютный адрес файла включающий его имя, если к примеру команде передан адрес дирректории(не важно относительный или абсолютный) то будет выведено только название элемента. Указанная информация в строек разделяется пробельными символами, причём для выравнивания информации пробельных символов может идти несколько подряд, что будет учтено далее при написании скрипта, не смотря на схожесть таких пробелов с табуляцией символы имеют именно код пробела. Примеры выполнения команды ls привереды на скринсшоте ниже.

Так же можно обработать результат возвращаемый командой ls с помощью awk так чтобы возвращалась только нужная информация, например поскольку для решения моей задачи(по крайней мере изначально) мне требовалось только название элемента и имя его владельца в операционной системы эту информацию можно получить выполнив команду ls -l | awk '{print $9,$3}' в дирректории для которой необходимо получить информацию или передать адрес элемента после флага -l. пример вывода команды ls с использованием awk приведён на скринсшоте ниже.

Для того чтобы получить использовать командную строку в PHP можно использовать функцию shell_exec которая вернёт результат выполнения команды в виде текста. Строки в возвращённом результате разделяются через \n без использования символа возврата каретки(\r). Таким образом для разделения строк в полученном от функции shell_exec тексте можно использовать функцию explode("\n",$shellresponse). В строке информация разделяется как уже указывалось выше через пробельные символами, которых может идти несколько подряд, таким образом для разделения элементов в строках полученных от shell_exec не получится просто использовать разделение по одному пробелу, поскольку так нужные элементы информации могут попасть не в ожидаемые элементы массива, для начала можно проверить нет ли за обнаруженным пробелом других пробелов, в итоге я переписал алгоритм следующим образом: для начала выполняется замена в строках полученных от shell_exec двух следующих друг за другом пробелов одним, затем проверяется остались ли ещё в рассматриваемой в foreach цикле строки пробелы следующие друг за другом и если да то замена двух пробелов одним продолжается до тех пор пока в строке не останутся пробелов следующих друг за другом, а останутся только одиночные. В коде я реализовал это строкой do {$llLine = str_replace(" "," ",$llLine);} while(strpos($llLine," ") !== false); после того как в рассматриваемой в цикле строке остались только одиночные пробелы можно использовать разделение по одному пробелу, то есть использовать функцию explode(" ",$llLine);

Поскольку в моём случаи мне требовалось получать информацию о владельце файлов и дирректорий для конкретной дирректории приведённый ниже код предполагает передачу в качестве адреса команде ll адрес дирректории. Было решено предварительно собрать информацию о именах элементов и их владельцах в массив $elementsPermissionsAr каждый элемент которого содержит в себе массив из двух элементов, первый из которых - имя элемента, второй - его владелец. В следующем листинге приведён код получения указанной информации в массив $elementPermissionsAr.

Теперь необходимая информация собрана с массиве $elementsPermissionsAr, для получения информации из него я написал функцию которая принимает адрес элемента и если такой элемент найден возвращает имя владельца файла, если же элемент не найден функция возвращает false. Здесь же укажу, что в целом возможно имеет смысл описанный алгоритм(включая алгоритм сбора информации в массив $elementsPermissionsAr) организовать несколько иначе и например учитывать тип элемента в каталоге, то есть например является ли элемент файлом или каталогом. В случаи операционными системами линукс и CentOs в частности это не критично, поскольку каталог не может одновременно содержать файла и каталога с одинаковыми именами, в операционной системе Windows такое возможно, поэтому возможно я вернусь к этому вопросу позже и внесу некоторые правки в алгоритмы. Текущая же реализация не содержит указания на тип элемента каталога в массиве $elementsPermissionsAr.

//posix_getpwuid //posix_getpwuid(posix_getuid("/var/www/blog.ivru.net/test/file2.txt")); var_dump(posix_getuid("/var/www/blog.ivru.net/test/file2.txt")); var_dump(fileowner("/var/www/blog.ivru.net/test/file2.txt")); var_dump(get_current_user());

Не важно передан команде ls адрес файле или директории указанная команда вернёт строки(или строку в случаи файла) содержащие информацию разделённую пробелами, причём для разделения может использоваться несколько пробелов, это предположительно сделано для выравнивания при отображении информации в программах являющимися клиентами и предоставляющими возможность работать в командной строке.

var_dump(getElementPermissionsBeta("111111.php"));

Комментарии

Если у Вас возникли вопросы, Вы можете задать их в форме ниже. В частности если Ваш вопрос по Bitrix и что то не получается - можно спросить. Ваш e-mail не публикуется, при этом я отвечу на него если будет что то по теме. Писать необходимо для людей - избегайте сленга, пишите орфографически правильно.

Имя:
E-mail:
Текст комментария:

Вы так же можете прочитать следующие статьи: