PHP: полный мануал с примерами, функциями и ООП
Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Дерево руководства
Глава 136 · Практика
POSIX: процессы, пользователи, права, терминалы и лимиты Unix
Все41функции POSIX,45констант, диагностика worker, различие UID/GID и PID/PGID, системные ограничения и честная граница Unix.
POSIX: зачем PHP знать о процессе и его правах
Магазин запускает импорт каталога по расписанию. В терминале разработчика он читает файл, а у фонового worker — отказ; другой job исчерпал дескрипторы; несколько одновременно запущенных копий смешали строки журнала. POSIX позволяет спросить ОС: какой это процесс, кто он с точки зрения прав, какие у него группы и ограничения. При специальной необходимости отдельный launcher может изменить часть этих свойств.
Процесс — выполняющаяся программа со своей памятью, открытыми файлами и системной идентичностью. Файл worker.php сам по себе не процесс: два запуска одного файла получат два PID. UID/GID относятся к пользователям ОС, не к пользователям сайта. Изменение переменной $uid не меняет прав; системный вызов posix_setuid просит это сделать ядро, и ядро может отказать.
- PHP: $pid = posix_getpid()
- Расширение POSIX вызывает getpid в ОС
- ОС возвращает номер текущего процесса, например4127
- PHP сохраняет4127 в $pid
- Журнал использует этот номер вместе с отдельным ID запуска
<?php
declare(strict_types=1);
$worker = ['pid' => 4127, 'uid' => 1001, 'job' => 'catalog'];
echo 'Задание ', $worker['job'], ', PID ', $worker['pid'], "\n";
$worker['uid'] = 2000;
echo "Поменяли только число в массиве, права ОС остались прежними\n";
Ожидаемый результат
Задание catalog, PID 4127
Поменяли только число в массиве, права ОС остались прежними
Это маленькая модель с явно выдуманным PID, не настоящий системный вызов. Реальную идентичность читают функции POSIX. Подготовка: переменная, массив, вызов функции.
В карточке имя до скобок — функция; внутри скобок — аргументы. Вызов posix_getpid() не принимает аргументов и возвращает число. В posix_access($path, POSIX_R_OK) путь и именованная маска передаются на вход, на выходе bool. Проверка === false не путает отказ с допустимыми нулевыми значениями. Константа POSIX_R_OK задаёт режим проверки, а не строку для сохранения.
Установка, версии и граница платформы
Расширение POSIX входит в исходники PHP и обычно включено при Unix сборке; его можно отключить --disable-posix. Windows реализация этого расширения не поддерживается. Не путайте с PCRE POSIX character classes, pthreads или PCNTL. Дистрибутив может вынести модуль в отдельный пакет; точное имя пакета зависит от ОС и версии PHP. Наличие PHP8 само по себе не обещает наличие всех системных функций.
Проверяйте расширение в том SAPI, где работает код: CLI и PHP-FPM могут использовать разные бинарники/ini. Команды php --ini и php -m относятся к выбранному CLI. В POSIX нет собственных INI директив, новых resource типов и классов; результаты — числа, bool, строки и массивы. Некоторые функции условно компилируются, потому что libc не предоставляет соответствующего вызова. getrlimit/setsid и подобные системные возможности описаны в этой книге даже там, где исторически не были частью исходного стандарта POSIX.1.
<?php
declare(strict_types=1);
foreach (['posix_getpid', 'posix_geteuid', 'posix_eaccess', 'posix_fpathconf'] as $name) {
echo $name, ': ', function_exists($name) ? 'есть' : 'нет', "\n";
}
echo 'POSIX_SC_CLK_TCK: ', defined('POSIX_SC_CLK_TCK') ? 'есть' : 'нет', "\n";
Ожидаемый результат
Четыре строки о функциях и строка о константе, по фактической сборке.
Наличие функции проверено до выполнения. На Windows диагностический код работает, но выводит отсутствие POSIX API; он не включает Unix подсистему. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
База примеров — PHP8.5.11. eaccess, sysconf, pathconf, fpathconf и аргумент resource у getrlimit добавлены в8.3; CHILD_MAX/CLK_TCK —8.4; новые проверки аргументов ряда вызовов отмечены в карточках8.5. На Windows выполнены только независимые модели PHP; Unix действия проверены синтаксически и требуют отдельного совместимого CLI стенда. Смена UID/GID/сеанса и лимитов не запускается в рабочем запросе сайта.
Быстрый выбор по реальной задаче
| Вопрос | Нужный инструмент |
|---|---|
| Какой worker написал строку? | PID + отдельный ID запуска: posix_getpid. |
| Чьи права у процесса? | Effective UID/GID, supplementary groups; posix_geteuid, posix_getgroups. |
| Как называется этот UID? | Lookup NSS: posix_getpwuid. |
| Почему cron не пишет файл? | Путь CWD, identities, actual fopen error; posix_getcwd, posix_eaccess. |
| Почему не открывается новый socket? | FD budget: posix_getrlimit и утечки незакрытых дескрипторов. |
| Как уведомить свой worker? | Сигнал posix_kill + PCNTL handler; payload через отдельный канал. |
| Как запретить второй запуск? | Менеджер служб или удерживаемый lock. PID existence check недостаточен. |
| Как измерить CPU? | Дельта posix_times / CLK_TCK; latency измеряют отдельно. |
Последовательность чтения: наблюдение → диагностика → системные ограничения → изменения в отдельном процессе. Для самого сайта обычно достаточно обычных файловых функций, управления собственным дочерним процессом и сокетов. POSIX выбирают, когда задача действительно связана с Unix процессом, а не потому, что это «более низкий уровень».
Не путать пользователя, процесс, группу и сеанс
| Идентификатор | Значение |
|---|---|
| PID / PPID | Номер процесса / текущего родителя. Может быть переиспользован после завершения. |
| PGID / SID | Группа процессов / сеанс. Не Unix группа пользователей и не $_SESSION. |
| Real UID/GID | Исходные основные идентичности по правилам ОС. |
| Effective UID/GID | Действующие основные права для обычных проверок ОС. |
| Supplementary groups | Дополнительные группы уже запущенного процесса. |
| Saved IDs | Сохранённые идентичности ОС; возможность возврата зависит от механизма. POSIX PHP не предоставляет здесь универсальный просмотр/сброс всех capabilities. |
Модель «пропуск сотрудника» помогает: имя — подпись, UID — номер, группы — дополнительные разрешения. Ограничение аналогии: ACL, namespaces, capabilities и политики ОС сложнее одного пропуска. Один setuid не закрывает открытые раньше файлы и не делает процесс изолированным. Для обычного сервиса предпочтительно назначить пользователя/группы в менеджере служб до запуска PHP.
Все маски проверки доступа
| Константа | Для чего применяется |
|---|---|
POSIX_F_OK | Проверить существование; значение0, default flags. Не проверяет чтение. |
POSIX_R_OK | Проверить чтение. |
POSIX_W_OK | Проверить запись. |
POSIX_X_OK | Проверить выполнение файла; для каталога — право поиска/прохода. |
Флаги объединяют побитовым |. F_OK равен0; добавление его к R_OK не добавляет отдельной возможности. Право и факт существования проверяются в момент вызова; последующая операция обязана обработать свой отказ.
Все типы узлов mknod
| Константа | Для чего применяется |
|---|---|
POSIX_S_IFREG | Обычный файл; для сайта обычно проще fopen в режиме x. |
POSIX_S_IFCHR | Символьное устройство; major/minor выбирают устройство ядра, нужны соответствующие полномочия. |
POSIX_S_IFBLK | Блочное устройство; не способ создать обычный файл экспорта. |
POSIX_S_IFIFO | Именованный канал байтов; удобнее posix_mkfifo. |
POSIX_S_IFSOCK | Тип узла Unix socket; наличие узла не создаёт listening socket. Для канала используйте socket/stream API. |
Выберите один тип и объедините с восьмеричными правами. Константа может отсутствовать на данной сборке. major/minor относятся к устройствам, а не к permissions. Устройство не требуется для обычного обмена JSON между процессами.
Все ограничения ресурсов и их единицы
| Константа | Для чего применяется |
|---|---|
POSIX_RLIMIT_AS | Виртуальное адресное пространство процесса, байты; не только память, учтённая PHP memory_limit. |
POSIX_RLIMIT_CORE | Размер core dump, байты; soft0 запрещает такой файл по RLIMIT_CORE. |
POSIX_RLIMIT_CPU | CPU секунды; не время ожидания HTTP. Поведение soft/hard и сигналов зависит от ОС. |
POSIX_RLIMIT_DATA | Data segment/heap, байты; взаимодействие с mmap зависит от ОС/версии ядра. |
POSIX_RLIMIT_FSIZE | Предельный размер создаваемого/увеличиваемого файла, байты. Не размер data segment. |
POSIX_RLIMIT_LOCKS | Ограничение файловых locks/leases там, где ОС реализует его. На Linux историческое, не общий современный ограничитель flock. |
POSIX_RLIMIT_MEMLOCK | Байты памяти, которую разрешено закрепить в RAM; не общий лимит heap. |
POSIX_RLIMIT_MSGQUEUE | Бюджет POSIX message queues для real UID на поддерживающей ОС. Это не SysV очередь msg_get_queue. |
POSIX_RLIMIT_NICE | Граница изменения nice priority; Linux кодирует её как20−limit. Не передавайте желаемый отрицательный nice как лимит. |
POSIX_RLIMIT_NOFILE | Граница: на1 больше максимального допустимого номера дескриптора. Учитывайте файлы, sockets и pipes. |
POSIX_RLIMIT_NPROC | Количество процессов/потоков real UID по правилам ОС. Не просто количество PHP jobs одной программы. |
POSIX_RLIMIT_RSS | Resident memory, смысл и действие зависят от ОС. На современном Linux не рабочий способ ограничить RAM; исторический Linux предел измерялся в байтах, не универсальных «страницах». |
POSIX_RLIMIT_RTPRIO | Предел real-time priority на поддерживающей ОС; не рекомендует включать real-time планирование для сайта. |
POSIX_RLIMIT_RTTIME | На Linux микросекунды CPU real-time процесса без блокирующего системного вызова; не timeout произвольного PHP запроса. |
POSIX_RLIMIT_SIGPENDING | Предел очереди сигналов real UID; точные правила доставки/учёта определяет ОС. |
POSIX_RLIMIT_STACK | Максимальный стек процесса, байты. Глубина рекурсии PHP дополнительно зависит от движка и расширений. |
POSIX_RLIMIT_KQUEUES | Количество kqueue у real UID на поддерживающих BSD; константа PHP8.1+. |
POSIX_RLIMIT_NPTS | Количество pseudo-terminals real UID на поддерживающих BSD; PHP8.1+. |
POSIX_RLIMIT_INFINITY | Символическое значение отсутствия предела при setrlimit. Не строка "unlimited", которую возвращает getrlimit. |
Наличие имени в PHP зависит от headers/ОС. Семантика и фактическое применение некоторых лимитов платформенные. Нельзя выбрать случайное число мегабайт и передать его во все функции: FSIZE ждёт байты, CPU — секунды CPU, RTTIME — иной специальный счётчик. PHP memory_limit, supervisor/container quota и RLIMIT — разные границы.
Все селекторы sysconf
| Константа | Для чего применяется |
|---|---|
POSIX_SC_ARG_MAX | Бюджет argv+environment для запуска программы, байты; нельзя целиком отдать одному аргументу. |
POSIX_SC_CHILD_MAX | Предел дочерних процессов/процессов real UID по ОС; PHP8.4+. |
POSIX_SC_CLK_TCK | Количество clock ticks в секунду для times; PHP8.4+. |
POSIX_SC_PAGESIZE | Размер страницы памяти ОС в байтах. |
POSIX_SC_NPROCESSORS_CONF | Количество настроенных процессоров. |
POSIX_SC_NPROCESSORS_ONLN | Количество процессоров online, не гарантированная CPU quota контейнера. |
POSIX_SC_OPEN_MAX | Предел открытых дескрипторов sysconf; есть в tagged PHP8.5.11 stub, хотя отдельная страница констант Manual его не перечисляет. Проверяйте defined. |
Параметры памяти/CPU появились вместе с sysconf PHP8.3, отдельные новые константы отмечены выше. Недоступное/отрицательное значение не используйте как положительный размер; выбирайте явную политику fallback. Предел argv включает окружение, поэтому большой JSON обычно передают через stdin/файл, а не одним аргументом командной строки.
Все селекторы pathconf и fpathconf
| Константа | Для чего применяется |
|---|---|
POSIX_PC_LINK_MAX | Максимум жёстких ссылок на файл. |
POSIX_PC_MAX_CANON | Предел строки канонического ввода терминала, байты. |
POSIX_PC_MAX_INPUT | Предел очереди входа терминала, байты. |
POSIX_PC_NAME_MAX | Длина одного компонента имени в каталоге, байты. |
POSIX_PC_PATH_MAX | Предел относительного пути для указанного каталога по правилам ОС; не универсальная длина всех абсолютных путей. |
POSIX_PC_PIPE_BUF | Размер записи в pipe, для которой ОС гарантирует атомарность при её условиях; не общая ёмкость pipe. |
POSIX_PC_CHOWN_RESTRICTED | Признак ограничений смены владельца/группы; не размер. |
POSIX_PC_NO_TRUNC | Признак ошибки вместо усечения слишком длинного имени; не количество символов. |
POSIX_PC_ALLOC_SIZE_MIN | Минимальный размер выделяемого файлового блока в байтах там, где поддерживается. |
POSIX_PC_SYMLINK_MAX | Предел содержимого символической ссылки в байтах; не количество переходов при разрешении пути. |
Все относятся к POSIX pathconf API PHP8.3+. В снимке отдельной страницы Manual ошибочно встречается POSIX_PC_ALLOC_SYMLINK_MAX; в сигнатурной документации и tagged PHP8.5.11 stub правильное имя POSIX_PC_SYMLINK_MAX. Лишнее имя не предлагается как рабочая константа. Для строковых имён файлов считают байты через strlen, а не пользовательские символы через mb_strlen. PIPE_BUF не ёмкость FIFO и не гарантия атомарности произвольной серии fwrite.
Ошибки, стоимость и правильная интерпретация результата
Одинаковый внешне false имеет разный смысл: isattyfalse при перенаправлении — нормальная ветка; getpwuidfalse — не получена запись; accessfalse — проверка не прошла. setsid отказывает значением-1, sysconf также может вернуть-1, но по другой причине. Сохранённый POSIX errno помогает только после wrapper, который действительно его записал; успешный вызов обычно не очищает старую ошибку.
<?php
declare(strict_types=1);
$answers = [0, false, -1, 'unlimited'];
foreach ($answers as $answer) {
echo json_encode($answer), ': ', $answer === false ? 'false' : 'другое значение', "\n";
}
Ожидаемый результат
0: другое значение
false: false
-1: другое значение
"unlimited": другое значение
Модель показывает различие значений. Отдельная карточка задаёт, какое именно из них означает отказ; нельзя придумать один if(!$result) для всех функций.
Стоимость тоже различается: getter PID/UID не эквивалентен NSS lookup, который способен обратиться к сети. Чтение pathconf касается конкретной файловой системы. Не вызывайте десятки системных диагностик в каждом HTTP ответе без необходимости; снимок на запуск worker и отчёт по отказу часто полезнее. При этом кэш имён/групп не должен навсегда скрывать изменение политик. Производительность измеряют в своей среде, а не объявляют «эта функция медленная» без условий.
Полный указатель и задача для закрепления
| Подкатегория | Полный перечень функций |
|---|---|
| Идентичность и справочники ОС | posix_getuid, posix_geteuid, posix_getgid, posix_getegid, posix_getgroups, posix_getlogin, posix_getpwuid, posix_getpwnam, posix_getgrgid, posix_getgrnam |
| Изменение идентичности | posix_setuid, posix_setgid, posix_seteuid, posix_setegid, posix_initgroups |
| Процессы, группы, сеансы, сигналы | posix_getpid, posix_getppid, posix_getpgrp, posix_getpgid, posix_getsid, posix_setpgid, posix_setsid, posix_kill |
| Файлы, доступ и терминалы | posix_access, posix_eaccess, posix_getcwd, posix_mkfifo, posix_mknod, posix_isatty, posix_ttyname, posix_ctermid |
| Система, лимиты, счётчики и ошибки | posix_uname, posix_times, posix_getrlimit, posix_setrlimit, posix_sysconf, posix_pathconf, posix_fpathconf, posix_get_last_error, posix_errno, posix_strerror |
Учебная задача: worker не читает каталог, и коллега предлагает выполнить chmod777. Сначала составьте локальный отчёт, который показывает текущую директорию, effective UID/GID, состав групп и результат проверки чтения. Не изменяйте права и не выводите полный passwd record. Затем сопоставьте данные с фактическим отказом открытия файла.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || !extension_loaded('posix')) throw new RuntimeException('Нужен Unix CLI POSIX');
$path = __DIR__ . '/catalog.txt';
$report = [
'pid' => posix_getpid(),
'cwd' => posix_getcwd(),
'euid' => posix_geteuid(),
'egid' => posix_getegid(),
'supplementary_groups' => posix_getgroups(),
];
if (function_exists('posix_eaccess')) $report['effective_read_check'] = posix_eaccess($path, POSIX_R_OK);
echo json_encode($report, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), "\n";
Ожидаемый результат
JSON с текущими процессными данными; без изменения прав.
Если eaccess отсутствует, поле не выдаётся за подтверждённый доступ. CWD/getgroups могут вернутьfalse — отчёт сохраняет это как неизвестное состояние. Дальнейший fopen по-прежнему отдельно обрабатывает отказ. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Следующий шаг: добавьте этот отчёт в локальную диагностику запуска worker, затем сравните CLI и службу с их реальной конфигурацией. Для ограничения параллельных запусков изучите семафоры и процессы либо менеджер задач/удерживаемый файловый lock; для IPC данных — потоки. Не используйте PID из журнала как постоянный адрес процесса.
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
posix_getuidУзнать реальный UID процесса: под какой исходной системной идентичностью запущен обработчик. Это число ОС, не ID покупателя из базы сайта.
PHP4+ · posix (Unix)
posix_getuid(): intУзнать реальный UID процесса: под какой исходной системной идентичностью запущен обработчик. Это число ОС, не ID покупателя из базы сайта.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getuid(): int |
| Вход | Нет параметров; пустые скобки запускают получение значения. |
| Результат и отказ | Целый real UID; 0 — допустимый UID root, а не false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Обычно real и effective UID одинаковы, но при изменении привилегий могут различаться. Для проверки текущих файловых прав рассматривайте effective UID, группы, ACL и другие ограничения ОС.
<?php
declare(strict_types=1);
$uid = posix_getuid();
echo 'Real UID: ', $uid, "\n";
Ожидаемый результат
Например Real UID: 1000; значение относится к текущему процессу.
Сначала ОС вернула число; оператор = сохранил его в $uid; echo показывает значение. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$real = posix_getuid();
$effective = posix_geteuid();
echo $real === $effective ? "UID совпадают\n" : "UID различаются\n";
Ожидаемый результат
UID совпадают либо UID различаются.
Такой отчёт помогает понять запуск через привилегированный wrapper. Он не доказывает, кто вошёл на сайт, и не является полной проверкой доступа. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_geteuid, posix_getpwuid.
posix_geteuidПонять, с чьими текущими правами работает импорт каталога и почему ему отказано в записи.
PHP4+ · posix (Unix)
posix_geteuid(): intПонять, с чьими текущими правами работает импорт каталога и почему ему отказано в записи.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_geteuid(): int |
| Вход | Нет. |
| Результат и отказ | Effective UID как int; 0 не означает ошибку. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
get_current_user сообщает владельца PHP файла, а не текущую эффективную идентичность. getenv(USER), LOGNAME и SUDO_USER — окружение, не авторитетное доказательство прав.
<?php
declare(strict_types=1);
echo 'Effective UID: ', posix_geteuid(), "\n";
Ожидаемый результат
Строка с фактическим effective UID.
Не запускаем whoami через exec ради уже доступного системного вызова. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (posix_geteuid() === 0) {
fwrite(STDERR, "Импорт должен работать от отдельной непривилегированной учётной записи\n");
exit(1);
}
echo "UID подходит для обычного запуска\n";
Ожидаемый результат
Для UID0 — сообщение в stderr и код1; для другого UID — строка об обычном запуске.
Это конкретная политика job, не утверждение, что любое ненулевое значение гарантирует отсутствие Linux capabilities или полный sandbox. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getuid, posix_getpwuid, posix_seteuid.
posix_getgidПрочитать реальный основной GID процесса при разборе прав сервисной учётной записи.
PHP4+ · posix (Unix)
posix_getgid(): intПрочитать реальный основной GID процесса при разборе прав сервисной учётной записи.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getgid(): int |
| Вход | Нет. |
| Результат и отказ | Целый real GID, в том числе 0. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Основная группа — только часть идентичности. Дополнительные группы читаются отдельно; GID не обозначает роль администратора сайта.
<?php
declare(strict_types=1);
$gid = posix_getgid();
echo 'Real GID: ', $gid, "\n";
Ожидаемый результат
Строка с реальным GID.
Число можно сохранить в диагностике запуска. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$gid = posix_getgid();
$group = posix_getgrgid($gid);
echo $group === false ? "Нет записи группы для GID $gid\n" : 'Группа: ' . $group['name'] . "\n";
Ожидаемый результат
Название найденной системной группы либо явное сообщение об отсутствии записи.
Процесс может иметь числовую группу, для которой нет записи в доступной NSS базе, например внутри контейнера. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getegid, posix_getgroups, posix_getgrgid.
posix_getegidУзнать текущую основную группу, участвующую в проверке прав процесса.
PHP4+ · posix (Unix)
posix_getegid(): intУзнать текущую основную группу, участвующую в проверке прав процесса.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getegid(): int |
| Вход | Нет. |
| Результат и отказ | Effective GID как int. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Добавление пользователя в группу в системной базе не меняет автоматически уже запущенный worker: новый состав групп обычно получают при новом запуске.
<?php
declare(strict_types=1);
echo 'Effective GID: ', posix_getegid(), "\n";
Ожидаемый результат
Строка с effective GID.
Сравнивайте с владельцем/группой каталога при разборе отказа записи. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$extra = posix_getgroups();
if ($extra === false) throw new RuntimeException('Не прочитаны дополнительные группы');
$groups = array_values(array_unique([posix_getegid(), ...$extra]));
echo implode(', ', $groups), "\n";
Ожидаемый результат
Уникальные числовые GID текущего процесса.
getgroups не обязан включать основную эффективную группу на каждой ОС, поэтому добавляем её явно. Это диагностика; ACL и особенности файловой системы всё ещё имеют значение. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getgid, posix_getgroups, posix_setegid.
posix_getgroupsПосмотреть дополнительные группы уже работающего импортёра: почему новое членство из настроек ОС ещё не действует.
PHP4+ · posix (Unix)
posix_getgroups(): array|falseПосмотреть дополнительные группы уже работающего импортёра: почему новое членство из настроек ОС ещё не действует.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getgroups(): array|false |
| Вход | Нет. |
| Результат и отказ | Список целых GID либо false. Пустой список допустим. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Список принадлежит процессу, а не произвольно выбранному имени пользователя. Не заменяет его чтение поля members одной группы: там могут отсутствовать пользователи с этой группой в качестве основной.
<?php
declare(strict_types=1);
$groups = posix_getgroups();
if ($groups === false) throw new RuntimeException('Группы недоступны');
echo 'Дополнительных групп: ', count($groups), "\n";
Ожидаемый результат
Дополнительных групп: N.
Проверка === false сохраняет различие между отказом и нормальным пустым массивом. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$target = posix_getgrnam('catalog-export');
if ($target === false) throw new RuntimeException('На стенде нужна группа catalog-export');
$groups = posix_getgroups();
if ($groups === false) throw new RuntimeException('Не прочитаны группы процесса');
$member = in_array($target['gid'], [posix_getegid(), ...$groups], true);
echo $member ? "Группа экспорта присутствует\n" : "Нужен запуск с нужным составом групп\n";
Ожидаемый результат
Одна из двух строк о членстве; при отсутствии настроенной группы — исключение.
Проверяем собственную сервисную среду перед экспортом. Это не обещает успешного fopen: фактическая операция тоже должна обработать отказ. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getegid, posix_getgrnam, posix_initgroups.
posix_getloginПолучить имя терминального входа для локальной CLI диагностики, понимая, почему в cron оно часто недоступно.
PHP4+ · posix (Unix)
posix_getlogin(): string|falseПолучить имя терминального входа для локальной CLI диагностики, понимая, почему в cron оно часто недоступно.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getlogin(): string|false |
| Вход | Нет. |
| Результат и отказ | Имя login session либо false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Underlying getlogin относится к терминальному входу и не является надёжным именем effective UID; daemon, контейнер и cron могут не иметь login record. Не используйте это значение для авторизации.
<?php
declare(strict_types=1);
$login = posix_getlogin();
echo $login === false ? "Терминальный login недоступен\n" : "Login: $login\n";
Ожидаемый результат
Имя login либо сообщение об отсутствии.
Отсутствие записи у фонового job не означает, что ОС не знает его UID. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$login = posix_getlogin();
$account = posix_getpwuid(posix_geteuid());
echo 'Login session: ', $login === false ? 'нет' : $login, "\n";
echo 'Effective account: ', $account === false ? 'нет записи' : $account['name'], "\n";
Ожидаемый результат
Две подписанные строки; значения могут различаться.
При sudo терминальный login и действующая учётная запись — разные вопросы. Нельзя молча выдавать одно за другое. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_geteuid, posix_getpwuid.
posix_getpwuidПреобразовать числовой UID worker в понятное имя и получить профиль системной учётной записи.
PHP4+ · posix (Unix)
posix_getpwuid(int $user_id): array|falseПреобразовать числовой UID worker в понятное имя и получить профиль системной учётной записи.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getpwuid(int $user_id): array|false |
| Вход | UID как int, полученный из ОС или проверенной конфигурации. |
| Результат и отказ | Ассоциативный массив либо false при отсутствии записи/ошибке. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Числовой UID может быть действительным для процесса и отсутствовать в NSS. Ошибка не всегда означает ненулевой свежий errno; не делайте вывода «пользователя точно нет» только по старому posix_get_last_error.
Запись пользователя содержит name (имя), uid/gid (числа), gecos (описание), dir (домашний каталог), shell (login shell), passwd (обычно маркер x/*, не открытый пароль). В tagged PHP8.5 строковые поля могут быть null, если libc не предоставила их. Эти данные не проверяют пароль и не должны публиковаться целиком. Источник — системная база через NSS: это может быть LDAP/другая служба, а не только /etc/passwd; lookup может ждать сеть. Повторные запросы в цикле лучше убрать или кэшировать ограниченно.
<?php
declare(strict_types=1);
$uid = posix_geteuid();
$account = posix_getpwuid($uid);
echo $account === false ? "Worker UID=$uid без записи NSS\n" : 'Worker: ' . $account['name'] . "\n";
Ожидаемый результат
Имя worker либо числовой UID без найденной записи.
UID остаётся полезным даже при неудачном преобразовании в имя. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$account = posix_getpwuid(posix_geteuid());
if ($account === false) throw new RuntimeException('Нет системной записи');
$home = $account['dir'];
if (!is_string($home) || $home === '') throw new RuntimeException('Домашний каталог не задан');
echo 'Каталог в NSS: ', $home, "\n";
echo 'HOME окружения: ', getenv('HOME') === false ? 'не задан' : getenv('HOME'), "\n";
Ожидаемый результат
Две строки с каталогами; они могут различаться.
Чтение dir не создаёт каталог и не выдаёт права. Для состояния сервиса чаще задают отдельный абсолютный путь в конфигурации. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpwnam, posix_geteuid.
posix_getpwnamНайти заранее настроенную сервисную учётную запись по имени перед запуском фонового задания.
PHP4+ · posix (Unix)
posix_getpwnam(string $username): array|falseНайти заранее настроенную сервисную учётную запись по имени перед запуском фонового задания.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getpwnam(string $username): array|false |
| Вход | Системное имя; это не email и не аккаунт сайта. |
| Результат и отказ | Запись пользователя со всеми полями ниже либо false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Не существует универсального лимита «16 символов» для всех NSS реализаций. Не передавайте непроверенные значения с NUL; поиск не создаёт пользователя и не подтверждает владение аккаунтом.
Запись пользователя содержит name (имя), uid/gid (числа), gecos (описание), dir (домашний каталог), shell (login shell), passwd (обычно маркер x/*, не открытый пароль). В tagged PHP8.5 строковые поля могут быть null, если libc не предоставила их. Эти данные не проверяют пароль и не должны публиковаться целиком. Источник — системная база через NSS: это может быть LDAP/другая служба, а не только /etc/passwd; lookup может ждать сеть. Повторные запросы в цикле лучше убрать или кэшировать ограниченно.
<?php
declare(strict_types=1);
$account = posix_getpwnam('catalog-worker');
if ($account === false) throw new RuntimeException('Настройте catalog-worker на учебном стенде');
echo 'UID=', $account['uid'], '; GID=', $account['gid'], "\n";
Ожидаемый результат
UID и GID настроенной учётной записи либо исключение.
Имя выбрано администратором в конфигурации, не получено из формы посетителя. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$current = posix_getpwuid(posix_geteuid());
if ($current === false || !is_string($current['name'])) throw new RuntimeException('Нет имени');
$byName = posix_getpwnam($current['name']);
echo $byName !== false && $byName['uid'] === $current['uid']
? "Имя и UID согласованы\n" : "Запись изменилась или lookup не удался\n";
Ожидаемый результат
Строка о согласованности либо изменении/отказе.
Два lookup не образуют транзакцию: каталог пользователей может изменяться. Не используйте roundtrip как процедуру входа на сайт. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpwuid, posix_initgroups, posix_setuid.
posix_getgrgidПодписать числовые группы процесса человекочитаемыми именами в локальном отчёте.
PHP4+ · posix (Unix)
posix_getgrgid(int $group_id): array|falseПодписать числовые группы процесса человекочитаемыми именами в локальном отчёте.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getgrgid(int $group_id): array|false |
| Вход | GID как int. |
| Результат и отказ | Массив записи либо false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Проверяйте false до доступа по ключам. Отсутствие имени не обнуляет идентификатор группы и не снимает её права.
Поля группы: name, passwd, gid, members — список имён. passwd обычно служебный маркер. members перечисляет записанное членство, но не обязательно всех пользователей, у которых этот GID основной. База может быть сетевой, поэтому lookup не стоит повторять для каждой строки большого отчёта.
<?php
declare(strict_types=1);
$gid = posix_getegid();
$group = posix_getgrgid($gid);
echo $group === false ? "GID=$gid\n" : $group['name'] . "\n";
Ожидаемый результат
Имя группы либо GID=N.
Показан явный запасной вариант без потери числовой идентичности. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$extra = posix_getgroups();
if ($extra === false) throw new RuntimeException('Группы недоступны');
foreach (array_unique([posix_getegid(), ...$extra]) as $gid) {
$group = posix_getgrgid($gid);
echo $gid, ': ', $group === false ? '(нет записи)' : $group['name'], "\n";
}
Ожидаемый результат
Одна строка GID: имя для каждой уникальной группы.
Сначала устраняем повторы, затем обращаемся к NSS. Это отчёт владельцу сервиса, а не публичная страница. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getgroups, posix_getgrnam.
posix_getgrnamПолучить номер настроенной группы каталога по понятному имени.
PHP4+ · posix (Unix)
posix_getgrnam(string $name): array|falseПолучить номер настроенной группы каталога по понятному имени.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getgrnam(string $name): array|false |
| Вход | Имя группы ОС. |
| Результат и отказ | Массив name/passwd/gid/members либо false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это чтение системного справочника, не изменение групп процесса. Сравнение members с именем не заменяет getgroups для проверки действующего worker.
Поля группы: name, passwd, gid, members — список имён. passwd обычно служебный маркер. members перечисляет записанное членство, но не обязательно всех пользователей, у которых этот GID основной. База может быть сетевой, поэтому lookup не стоит повторять для каждой строки большого отчёта.
<?php
declare(strict_types=1);
$group = posix_getgrnam('catalog-export');
if ($group === false) throw new RuntimeException('Группа catalog-export недоступна');
echo 'GID экспорта: ', $group['gid'], "\n";
Ожидаемый результат
Строка с GID либо исключение при отсутствии настройки.
Числовой GID затем может использовать доверенный launcher, а не посетитель сайта. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$group = posix_getgrnam('catalog-export');
if ($group === false) throw new RuntimeException('Нет записи группы');
echo 'Явных записей members: ', count($group['members']), "\n";
foreach ($group['members'] as $member) echo $member, "\n";
Ожидаемый результат
Количество и имена из members; пустой список возможен.
Это именно содержимое записи. Пользователь с основной группой catalog-export может не оказаться в members; в уроке не делаем ошибочный отказ доступа из такого отсутствия. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getgrgid, posix_getgroups, posix_setgid.
posix_setuidПосле ограниченной стартовой операции передать дальнейшую работу отдельной сервисной идентичности.
PHP4+ · posix (Unix)
posix_setuid(int $user_id): boolПосле ограниченной стартовой операции передать дальнейшую работу отдельной сервисной идентичности.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setuid(int $user_id): bool |
| Вход | Целый UID из доверенной системной записи, не из HTTP запроса. |
| Результат и отказ | true — системный вызов выполнен; false — отказ, обычно с errno. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
На Linux привилегированный setuid меняет real/effective/saved UID; такой сброс обычно необратим. Непривилегированный процесс ограничен разрешёнными real/saved UID. Вызов не назначает основные или дополнительные группы автоматически. Проверяйте отказ даже при UID0.
Меняется идентичность всего процесса, не отдельной PHP переменной. Поэтому такие вызовы нельзя вставлять в обработчик посетителя внутри долгоживущего PHP-FPM worker. Обычный сайт запускают сразу с назначенными сервисными правами. Привилегированный launcher — отдельная задача администрирования: закрытие лишних дескрипторов, окружение, capabilities и ограничения контейнера тоже требуют настройки. Набор ниже показывает конкретный механизм UID/GID, а не универсальный sandbox.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен отдельный CLI');
$uid = posix_getuid();
if (!posix_setuid($uid)) throw new RuntimeException('ОС отклонила setuid');
echo 'Effective UID после вызова: ', posix_geteuid(), "\n";
Ожидаемый результат
Текущий effective UID либо исключение при отказе ОС.
Пример без выбора чужого пользователя. Даже установка своего UID не является переносимой гарантией успешности на любой системе. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || posix_geteuid() !== 0) {
throw new RuntimeException('Только отдельный привилегированный учебный launcher');
}
$account = posix_getpwnam('catalog-worker');
if ($account === false || $account['uid'] === 0 || $account['gid'] === 0) {
throw new RuntimeException('Нужна настроенная непривилегированная учётная запись');
}
if (!posix_initgroups($account['name'], $account['gid'])) {
throw new RuntimeException('Не назначены дополнительные группы');
}
if (!posix_setgid($account['gid'])) throw new RuntimeException('Не назначен GID');
if (!posix_setuid($account['uid'])) throw new RuntimeException('Не назначен UID');
if (posix_geteuid() !== $account['uid'] || posix_getegid() !== $account['gid']) {
throw new RuntimeException('Идентичность не совпала');
}
echo "Учебный launcher перешёл к идентичности worker\n";
Ожидаемый результат
При успешной настройке: Учебный launcher перешёл к идентичности worker.
Последовательность initgroups → setgid → setuid оставляет необходимые стартовые полномочия до настройки групп. Любая ошибка останавливает дальнейший запуск, вместо продолжения с неожиданными правами. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getuid, posix_geteuid, posix_setgid, posix_initgroups.
posix_setgidНазначить основную группу фонового процесса до отказа от стартовых привилегий.
PHP4+ · posix (Unix)
posix_setgid(int $group_id): boolНазначить основную группу фонового процесса до отказа от стартовых привилегий.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setgid(int $group_id): bool |
| Вход | Целый GID. |
| Результат и отказ | true либо false; проверить отказ до продолжения работы. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
У привилегированного процесса Linux меняет real/effective/saved GID. Дополнительные группы сохраняются, если не назначить их отдельно. Поэтому один setgid не удаляет старые групповые полномочия.
Меняется идентичность всего процесса, не отдельной PHP переменной. Поэтому такие вызовы нельзя вставлять в обработчик посетителя внутри долгоживущего PHP-FPM worker. Обычный сайт запускают сразу с назначенными сервисными правами. Привилегированный launcher — отдельная задача администрирования: закрытие лишних дескрипторов, окружение, capabilities и ограничения контейнера тоже требуют настройки. Набор ниже показывает конкретный механизм UID/GID, а не универсальный sandbox.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен отдельный CLI');
$gid = posix_getgid();
if (!posix_setgid($gid)) throw new RuntimeException('ОС отклонила GID');
echo 'Effective GID: ', posix_getegid(), "\n";
Ожидаемый результат
Строка с GID либо отказ.
Скобки получают одно число; проверка bool относится к операции, а не к числовому GID0. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || posix_geteuid() !== 0) {
throw new RuntimeException('Только отдельный привилегированный учебный launcher');
}
$account = posix_getpwnam('catalog-worker');
if ($account === false || $account['uid'] === 0 || $account['gid'] === 0) {
throw new RuntimeException('Нужна настроенная непривилегированная учётная запись');
}
if (!posix_initgroups($account['name'], $account['gid'])) {
throw new RuntimeException('Не назначены дополнительные группы');
}
if (!posix_setgid($account['gid'])) throw new RuntimeException('Не назначен GID');
if (!posix_setuid($account['uid'])) throw new RuntimeException('Не назначен UID');
if (posix_geteuid() !== $account['uid'] || posix_getegid() !== $account['gid']) {
throw new RuntimeException('Идентичность не совпала');
}
echo "Учебный launcher перешёл к идентичности worker\n";
Ожидаемый результат
При успехе — строка о переходе к worker.
Основной GID выбран из passwd записи, а дополнительные группы назначены отдельно. Копируемая программа полностью показывает порядок; после завершения одноразового процесса изменения исчезают вместе с ним. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getgid, posix_getegid, posix_initgroups, posix_setuid.
posix_seteuidИзменить именно effective UID в специальном launcher, сохранив различие между текущими и сохранёнными полномочиями.
PHP4+ · posix (Unix)
posix_seteuid(int $user_id): boolИзменить именно effective UID в специальном launcher, сохранив различие между текущими и сохранёнными полномочиями.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_seteuid(int $user_id): bool |
| Вход | Целый effective UID, разрешённый ОС. |
| Результат и отказ | true либо false; функция зависит от поддержки seteuid при сборке. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это не равнозначно окончательному сбросу всех привилегий. На Linux допускаются real/effective/saved UID или переход при CAP_SETUID; обычный worker не может выбрать произвольного пользователя. Мы не оставляем привилегированный PHP-FPM между запросами.
Меняется идентичность всего процесса, не отдельной PHP переменной. Поэтому такие вызовы нельзя вставлять в обработчик посетителя внутри долгоживущего PHP-FPM worker. Обычный сайт запускают сразу с назначенными сервисными правами. Привилегированный launcher — отдельная задача администрирования: закрытие лишних дескрипторов, окружение, capabilities и ограничения контейнера тоже требуют настройки. Набор ниже показывает конкретный механизм UID/GID, а не универсальный sandbox.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен CLI');
$effective = posix_geteuid();
echo posix_seteuid($effective) ? "Вызов принят\n" : "ОС отклонила вызов\n";
Ожидаемый результат
Вызов принят либо ОС отклонила вызов.
Некоторые POSIX реализации могут отклонять даже установку текущего значения. Результат не игнорируется. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен CLI');
$real = posix_getuid();
if (!posix_seteuid($real)) throw new RuntimeException('Не изменён effective UID');
echo 'Real=', posix_getuid(), '; effective=', posix_geteuid(), "\n";
Ожидаемый результат
Real и effective показывают исходный real UID.
На обычном непривилегированном запуске числа и так одинаковы. На специальном set-ID запуске это может снизить effective права, но saved UID и другие привилегии нельзя считать удалёнными. Для окончательного сброса см. setuid. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_geteuid, posix_getuid, posix_setuid.
posix_setegidИзменить эффективную основную группу процесса без обещания смены всей групповой идентичности.
PHP4+ · posix (Unix)
posix_setegid(int $group_id): boolИзменить эффективную основную группу процесса без обещания смены всей групповой идентичности.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setegid(int $group_id): bool |
| Вход | Целый GID, допускаемый ОС. |
| Результат и отказ | true или false; доступность зависит от сборки. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Смена effective GID не пересчитывает дополнительные группы. В частности, простое членство в supplementary group не всегда разрешает setegid на её номер: правила setegid опираются на real/effective/saved GID и привилегии.
Меняется идентичность всего процесса, не отдельной PHP переменной. Поэтому такие вызовы нельзя вставлять в обработчик посетителя внутри долгоживущего PHP-FPM worker. Обычный сайт запускают сразу с назначенными сервисными правами. Привилегированный launcher — отдельная задача администрирования: закрытие лишних дескрипторов, окружение, capabilities и ограничения контейнера тоже требуют настройки. Набор ниже показывает конкретный механизм UID/GID, а не универсальный sandbox.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен CLI');
$gid = posix_getegid();
if (!posix_setegid($gid)) throw new RuntimeException('EGID не установлен');
echo 'EGID=', posix_getegid(), "\n";
Ожидаемый результат
EGID=N либо исключение.
Не подменяем успешность предположением «это же текущая группа». Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен CLI');
$real = posix_getgid();
$before = posix_getgroups();
if (!posix_setegid($real)) throw new RuntimeException('Группа не изменена');
$after = posix_getgroups();
echo 'EGID=', posix_getegid(), "\n";
echo $before !== false && $after !== false && $before === $after
? "Дополнительные группы не изменились\n" : "Проверьте состав групп\n";
Ожидаемый результат
Новый EGID и строка о дополнительных группах.
Так видно, что основной GID и список дополнительных групп — разные свойства процесса. Для пересчёта списка есть initgroups. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getegid, posix_setgid, posix_getgroups, posix_initgroups.
posix_initgroupsНазначить процессу дополнительные группы выбранной учётной записи при подготовке отдельного worker.
PHP5.2+ · posix (Unix)
posix_initgroups(string $username, int $group_id): boolНазначить процессу дополнительные группы выбранной учётной записи при подготовке отдельного worker.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_initgroups(string $username, int $group_id): bool |
| Вход | username — системное имя; group_id — базовый GID, который также включается. |
| Результат и отказ | true при успехе, false при отказе или пустом имени. |
| Среда и версия | PHP5.2+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Функция не просто вычисляет массив: libc меняет supplementary groups процесса и обычно требует CAP_SETGID/root. В PHP8.5.11 wrapper не записывает новый POSIX last_error после initgroups, поэтому старый errno не выдаём за причину этого отказа.
Меняется идентичность всего процесса, не отдельной PHP переменной. Поэтому такие вызовы нельзя вставлять в обработчик посетителя внутри долгоживущего PHP-FPM worker. Обычный сайт запускают сразу с назначенными сервисными правами. Привилегированный launcher — отдельная задача администрирования: закрытие лишних дескрипторов, окружение, capabilities и ограничения контейнера тоже требуют настройки. Набор ниже показывает конкретный механизм UID/GID, а не универсальный sandbox.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || posix_geteuid() !== 0) throw new RuntimeException('Нужен отдельный привилегированный стенд');
$account = posix_getpwnam('catalog-worker');
if ($account === false || $account['uid'] === 0) throw new RuntimeException('Нет непривилегированного worker');
if (!posix_initgroups($account['name'], $account['gid'])) throw new RuntimeException('initgroups не выполнен');
$groups = posix_getgroups();
if ($groups === false) throw new RuntimeException('Список не прочитан');
echo 'Назначено дополнительных GID: ', count($groups), "\n";
Ожидаемый результат
Количество назначенных групп либо явный отказ.
Эта отдельная демонстрация заканчивается сразу: она ещё не сменила UID и не запускает обработку данных. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || posix_geteuid() !== 0) {
throw new RuntimeException('Только отдельный привилегированный учебный launcher');
}
$account = posix_getpwnam('catalog-worker');
if ($account === false || $account['uid'] === 0 || $account['gid'] === 0) {
throw new RuntimeException('Нужна настроенная непривилегированная учётная запись');
}
if (!posix_initgroups($account['name'], $account['gid'])) {
throw new RuntimeException('Не назначены дополнительные группы');
}
if (!posix_setgid($account['gid'])) throw new RuntimeException('Не назначен GID');
if (!posix_setuid($account['uid'])) throw new RuntimeException('Не назначен UID');
if (posix_geteuid() !== $account['uid'] || posix_getegid() !== $account['gid']) {
throw new RuntimeException('Идентичность не совпала');
}
echo "Учебный launcher перешёл к идентичности worker\n";
Ожидаемый результат
При успехе — строка о переходе к worker.
Если сначала сделать setuid, может не хватить полномочий для initgroups. Новый запуск по системной конфигурации обычно проще и надёжнее ручного переключения в приложении. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getgroups, posix_getpwnam, posix_setgid, posix_setuid.
posix_getpidДобавить номер worker к журналу, чтобы отличать одновременно работающие импорты.
PHP4+ · posix (Unix)
posix_getpid(): intДобавить номер worker к журналу, чтобы отличать одновременно работающие импорты.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getpid(): int |
| Вход | Нет. |
| Результат и отказ | PID текущего процесса как int. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
PID не уникален навсегда: после завершения ОС может назначить его другой программе. В контейнере число относится к PID namespace. PID файла самого по себе недостаточно для надёжной блокировки повторного запуска.
<?php
declare(strict_types=1);
$pid = posix_getpid();
echo 'Worker PID: ', $pid, "\n";
Ожидаемый результат
Worker PID: N.
Это номер выполняющегося PHP процесса, а не номер заказа. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$run = bin2hex(random_bytes(6));
$pid = posix_getpid();
foreach (['start', 'catalog-loaded', 'done'] as $event) {
echo json_encode(['run' => $run, 'pid' => $pid, 'event' => $event], JSON_THROW_ON_ERROR), "\n";
}
Ожидаемый результат
Три JSON строки с одинаковыми run и pid, разными event.
Случайный run отделяет разные запуски даже при повторном использовании PID. Для запрета второго job используйте lock/supervisor; журнал не является замком. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getppid, posix_getpgrp, posix_kill.
posix_getppidУвидеть, какой процесс сейчас считается родителем PHP worker, при разборе запуска cron/supervisor.
PHP4+ · posix (Unix)
posix_getppid(): intУвидеть, какой процесс сейчас считается родителем PHP worker, при разборе запуска cron/supervisor.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getppid(): int |
| Вход | Нет. |
| Результат и отказ | Текущий parent PID. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
После смерти родителя процесс может быть переподчинён; в PID namespace возможен PPID0. PPID не обязательно PID shell, который вы видите, и не доказывает доверенность запуска.
<?php
declare(strict_types=1);
echo 'PID=', posix_getpid(), '; PPID=', posix_getppid(), "\n";
Ожидаемый результат
Два фактических номера процесса и родителя.
Лог помогает найти дерево запуска без выполнения ps. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$startedBy = posix_getppid();
$events = ['read-config', 'validate-job'];
foreach ($events as $event) echo $event, ': parent-at-start=', $startedBy, "\n";
echo 'parent-now=', posix_getppid(), "\n";
Ожидаемый результат
События с первоначальным PPID и отдельное текущее значение.
Сохранённое число — снимок. Нельзя отправлять сигнал «родителю при старте» намного позже без учёта его завершения и повторного использования PID. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpid, posix_getpgid.
posix_getpgrpУзнать группу процессов своего job: терминал и supervisor могут управлять группой целиком.
PHP4+ · posix (Unix)
posix_getpgrp(): intУзнать группу процессов своего job: терминал и supervisor могут управлять группой целиком.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getpgrp(): int |
| Вход | Нет. |
| Результат и отказ | Текущий process group ID, PGID. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Группа процессов не равна Unix группе пользователей GID. В одной PGID могут находиться PHP, shell и другие программы конвейера; необдуманный сигнал группе затронет их все.
<?php
declare(strict_types=1);
echo 'PID=', posix_getpid(), '; PGID=', posix_getpgrp(), "\n";
Ожидаемый результат
Два числа, которые могут совпасть или отличаться.
Совпадение PID и PGID означает лидерство группы, а не повышенные права. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$leader = posix_getpgrp() === posix_getpid();
echo $leader ? "Уже лидер группы: прямой setsid обычно откажет\n" : "Не лидер группы\n";
Ожидаемый результат
Одна из двух строк.
Это объясняет ограничение setsid; между проверкой и действием всё равно требуется обработать системный отказ. Новая session не равна созданию дочернего процесса. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpgid, posix_setpgid, posix_setsid.
posix_getpgidПолучить PGID заданного процесса для диагностики собственного дерева worker.
PHP4+ · posix (Unix)
posix_getpgid(int $process_id): int|falseПолучить PGID заданного процесса для диагностики собственного дерева worker.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getpgid(int $process_id): int|false |
| Вход | PID; 0 означает текущий процесс. |
| Результат и отказ | PGID как int либо false при отказе/исчезнувшем PID. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Функция условно компилируется на поддерживающих её ОС. Результат относится к моменту вызова: это не резервирование PID и не разрешение посылать сигнал.
<?php
declare(strict_types=1);
$group = posix_getpgid(0);
if ($group === false) throw new RuntimeException('PGID недоступен');
echo 'PGID=', $group, "\n";
Ожидаемый результат
PGID=N.
0 здесь служебное значение «я», а не несуществующий процесс. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$parent = posix_getppid();
if ($parent <= 0) throw new RuntimeException('Родитель не виден в этом namespace');
$parentGroup = posix_getpgid($parent);
if ($parentGroup === false) {
echo "Родитель уже завершился или недоступен\n";
} else {
echo $parentGroup === posix_getpgrp() ? "Общая группа процессов\n" : "Разные группы\n";
}
Ожидаемый результат
Общая/разные группы либо сообщение об отказе.
Не подставляем PPID0: для getpgid0 это был бы текущий процесс, и отчёт ложно описал бы родителя. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpgrp, posix_getppid, posix_setpgid.
posix_getsidПосмотреть принадлежность процесса к Unix сеансу, например после запуска через менеджер служб.
PHP4+ · posix (Unix)
posix_getsid(int $process_id): int|falseПосмотреть принадлежность процесса к Unix сеансу, например после запуска через менеджер служб.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getsid(int $process_id): int|false |
| Вход | PID; 0 — свой процесс. |
| Результат и отказ | SID (PGID лидера сеанса) либо false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это не session_id браузера и не PHP $_SESSION. В tagged8.5 PID должен быть неотрицательным и помещаться в диапазон pid_t: вне его ValueError. Доступ к чужим сеансам зависит от ОС.
<?php
declare(strict_types=1);
$sid = posix_getsid(0);
echo $sid === false ? "SID недоступен\n" : "SID=$sid\n";
Ожидаемый результат
SID=N либо сообщение об отказе.
Сеанс объединяет группы процессов; он не содержит заказы/корзину посетителя. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$sid = posix_getsid(posix_getpid());
if ($sid === false) throw new RuntimeException('Не прочитан SID');
echo 'PID=', posix_getpid(), '; PGID=', posix_getpgrp(), '; SID=', $sid, "\n";
Ожидаемый результат
Три подписанных идентификатора.
Несколько PGID могут принадлежать одному SID. Используйте эти метки при разборе терминального job control, а не как средство авторизации. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpgid, posix_setsid.
posix_setpgidВыделить собственный одноразовый job в группу процессов для дальнейшего управляемого жизненного цикла.
PHP4+ · posix (Unix)
posix_setpgid(int $process_id, int $process_group_id): boolВыделить собственный одноразовый job в группу процессов для дальнейшего управляемого жизненного цикла.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setpgid(int $process_id, int $process_group_id): bool |
| Вход | process_id0 — текущий процесс; process_group_id0 — использовать PID выбранного процесса как PGID. |
| Результат и отказ | true либо false; с PHP8.5 отрицательные/слишком большие аргументы вызывают ValueError. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Можно менять себя или допустимого собственного ребёнка в рамках сеанса; нельзя произвольно перетасовать чужие процессы или session leader. Ограничения exec и гонки запуска требуют обработки отказа.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен одноразовый CLI');
if (!posix_setpgid(0, 0)) throw new RuntimeException('ОС не разрешила новую группу');
echo 'PGID=', posix_getpgrp(), '; PID=', posix_getpid(), "\n";
Ожидаемый результат
При успехе PGID совпадает с PID; возможен отказ, например для session leader.
Пример заканчивается сразу, не посылает сигналы группе и не меняет родительскую shell. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_VERSION_ID < 80500) throw new RuntimeException('Урок ошибки рассчитан на PHP8.5');
try {
posix_setpgid(-1, 0);
} catch (ValueError $error) {
echo "Отрицательный PID не принимается setpgid\n";
}
Ожидаемый результат
Отрицательный PID не принимается setpgid.
У kill отрицательный PID имеет отдельный смысл, а у setpgid недопустим. Нельзя переносить значения между функциями по созвучию. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpgrp, posix_getpgid, posix_setsid.
posix_setsidСоздать новый Unix сеанс в специально выделенном дочернем CLI процессе.
PHP4+ · posix (Unix)
posix_setsid(): intСоздать новый Unix сеанс в специально выделенном дочернем CLI процессе.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setsid(): int |
| Вход | Нет. |
| Результат и отказ | Новый SID как int; при ошибке именно -1, не false. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
setsid не создаёт ребёнка, не запускает daemon полностью, не перенаправляет stdin/out/err и не меняет каталог. Лидер группы не может вызвать его успешно. В PHP8.5 wrapper возвращает setsid напрямую и не обновляет сохранённый posix_last_error; не приписывайте отказу старое сообщение.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен одноразовый CLI');
$sid = posix_setsid();
echo $sid === -1 ? "Новый сеанс не создан\n" : "Создан SID=$sid\n";
Ожидаемый результат
SID=N либо Новый сеанс не создан.
Проверка if (!$sid) ошибочна: -1 — truthy. Не меняйте сеанс длительно живущего рабочего процесса сайта. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || !function_exists('pcntl_fork')) throw new RuntimeException('Нужны Unix CLI, PCNTL и POSIX');
$child = pcntl_fork();
if ($child === -1) throw new RuntimeException('fork не выполнен');
if ($child === 0) {
$sid = posix_setsid();
echo $sid === -1 ? "Не создан сеанс ребёнка\n" : "Ребёнок создал новый сеанс\n";
exit($sid === -1 ? 1 : 0);
}
if (pcntl_waitpid($child, $status) !== $child) throw new RuntimeException('Ожидание ребёнка не выполнено');
echo "Родитель дождался собственного ребёнка\n";
Ожидаемый результат
Строка ребёнка о результате setsid, затем строка родителя.
Ребёнок наследует PGID родителя, но получает другой PID и обычно уже не лидер группы. Он сразу завершается; waitpid не оставляет zombie. Для production supervisor обычно запускает foreground worker сам. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getsid, posix_getpid, posix_getpgrp.
posix_killПередать сигнал собственному управляемому worker или проверить возможность отправки без фактического сигнала.
PHP4+ · posix (Unix)
posix_kill(int $process_id, int $signal): boolПередать сигнал собственному управляемому worker или проверить возможность отправки без фактического сигнала.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_kill(int $process_id, int $signal): bool |
| Вход | PID>0 — процесс; 0 — своя process group; -1 — широкий набор разрешённых процессов ОС; PID<-1 — группа abs(PID). signal0 ничего не отправляет. Именованные сигналы поставляет PCNTL. |
| Результат и отказ | true — запрос принят; false — например недостаточно прав/нет цели/неверный сигнал. Это не подтверждение выполнения обработчика или завершения процесса. PHP8.5 ValueError при PID вне диапазона платформы. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
signal0 — не health-check и не надёжный lock. Отказ может означать EPERM, а не отсутствие; PID может быть переиспользован сразу после проверки. Не посылайте сигнал PID из пользовательской формы или старого файла без собственной модели владения. SIGKILL нельзя перехватить; SIGTERM допускает обработку.
<?php
declare(strict_types=1);
$pid = posix_getpid();
echo posix_kill($pid, 0) ? "Сигнал своему PID разрешён\n" : "Проверка не удалась\n";
Ожидаемый результат
Одна строка результата проверки.
В отличие от названия kill вызов с0 никого не завершает. Даже успешная проверка не гарантирует, что бизнес-задача продвигается. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli' || !function_exists('pcntl_signal')) throw new RuntimeException('Нужны CLI и PCNTL');
$received = false;
pcntl_async_signals(true);
if (!pcntl_signal(SIGUSR1, function () use (&$received) { $received = true; })) {
throw new RuntimeException('Обработчик не установлен');
}
if (!posix_kill(posix_getpid(), SIGUSR1)) throw new RuntimeException('Сигнал не отправлен');
pcntl_signal_dispatch();
echo $received ? "Обработчик получил уведомление\n" : "Доставка ещё не подтверждена\n";
Ожидаемый результат
При обработанном сигнале — Обработчик получил уведомление.
Обработчик установлен до отправки и только меняет флаг. Это демонстрация уведомления, не передача JSON/заказа: для данных используют канал, socket или очередь. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getpid, posix_get_last_error, posix_strerror, posix_getpgrp.
posix_accessДиагностировать доступ к файлу с реальными UID/GID процесса, например при разборе привилегированного launcher.
PHP4+ · posix (Unix)
posix_access(string $filename, int $flags = 0): boolДиагностировать доступ к файлу с реальными UID/GID процесса, например при разборе привилегированного launcher.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_access(string $filename, int $flags = 0): bool |
| Вход | Путь; flags0 равен POSIX_F_OK, остальные маски можно объединять. |
| Результат и отказ | true — проверка прошла; false — отказ/нет пути/ограничение open_basedir; errno помогает диагностике. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Проверка real IDs может отличаться от последующего fopen, который использует effective права. Между проверкой и действием путь может измениться (TOCTOU). Не строят безопасное открытие по принципу «access вернулtrue, значит ошибка невозможна».
Флаги POSIX_F_OK/R_OK/W_OK/X_OK: существование, чтение, запись, выполнение/поиск в каталоге. Побитовое | объединяет требования. На каталогах X означает проход по пути, R — чтение списка имён, W обычно нужен для изменения записей вместе с X. Проверяется путь с учётом идентичности, а не только числовые биты chmod.
<?php
declare(strict_types=1);
$path = __DIR__ . '/catalog.txt';
echo posix_access($path, POSIX_R_OK) ? "Real UID может читать файл\n" : "Чтение не подтверждено\n";
Ожидаемый результат
Для доступной fixture — Real UID может читать файл.
filename передан строкой; R_OK просит чтение. Возвращается bool, а не содержимое файла. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$flags = POSIX_R_OK | POSIX_X_OK;
if (!posix_access(__DIR__, $flags)) {
$code = posix_get_last_error();
echo 'Каталог недоступен real IDs: ', $code, ' ', posix_strerror($code), "\n";
} else {
echo "Real IDs разрешают список и проход\n";
}
Ожидаемый результат
Сообщение об успешной диагностике либо код и текст отказа.
Не используем logical || вместо битового |: иначе два флага превратятся в bool. X у каталога не означает «выполнить каталог». Потенциально меняющийся путь всё равно проверяют в самой операции. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_eaccess, posix_getuid, posix_get_last_error.
posix_eaccessПроверить доступ с действующими effective UID/GID, когда выясняем права работающего worker.
PHP8.3+ · posix (Unix)
posix_eaccess(string $filename, int $flags = 0): boolПроверить доступ с действующими effective UID/GID, когда выясняем права работающего worker.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_eaccess(string $filename, int $flags = 0): bool |
| Вход | Путь и та же маска F_OK/R_OK/W_OK/X_OK. |
| Результат и отказ | bool; ошибка ОС — false; в tagged8.5 пустой неразрешимый путь вызывает ValueError. Доступно с8.3 при поддержке eaccess. |
| Среда и версия | PHP8.3+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это удобная диагностика, но не замена обработке fopen/fwrite. Политики ACL, mount, capabilities, open_basedir и изменения пути влияют на результат.
Флаги POSIX_F_OK/R_OK/W_OK/X_OK: существование, чтение, запись, выполнение/поиск в каталоге. Побитовое | объединяет требования. На каталогах X означает проход по пути, R — чтение списка имён, W обычно нужен для изменения записей вместе с X. Проверяется путь с учётом идентичности, а не только числовые биты chmod.
<?php
declare(strict_types=1);
if (!function_exists('posix_eaccess')) throw new RuntimeException('Нужна поддержка eaccess и PHP8.3+');
echo posix_eaccess(__DIR__ . '/catalog.txt', POSIX_R_OK)
? "Effective IDs могут читать каталог товаров\n" : "Чтение не подтверждено\n";
Ожидаемый результат
Для доступного файла — строка об effective чтении.
Вход — путь к данным, выход — только ответ на проверку доступа. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$path = __DIR__ . '/catalog.txt';
echo 'Real: ', posix_access($path, POSIX_R_OK) ? 'да' : 'нет', "\n";
echo 'Effective: ', posix_eaccess($path, POSIX_R_OK) ? 'да' : 'нет', "\n";
Ожидаемый результат
Две строки; обычный запуск обычно даёт одинаковый ответ.
Различие возможно в специальном launcher с разными IDs. Проверки не читают файл и не подтверждают целостность его содержимого. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_access, posix_geteuid, posix_getegid.
posix_getcwdПонять, почему относительный путь cron job указывает не туда, куда ожидал разработчик.
PHP4+ · posix (Unix)
posix_getcwd(): string|falseПонять, почему относительный путь cron job указывает не туда, куда ожидал разработчик.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getcwd(): string|false |
| Вход | Нет. |
| Результат и отказ | Абсолютный текущий рабочий каталог или false с POSIX errno. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Рабочий каталог меняется через chdir и может отличаться от __DIR__ файла. Отказ возможен после удаления каталога или из-за отсутствия права поиска по пути. Для переносимого кода есть обычный getcwd.
<?php
declare(strict_types=1);
$working = posix_getcwd();
if ($working === false) throw new RuntimeException('Рабочий каталог не определён');
echo 'CWD: ', $working, "\n";
echo 'Каталог скрипта: ', __DIR__, "\n";
Ожидаемый результат
Два абсолютных пути, которые не обязаны совпасть.
Открытие catalog.txt ищет относительно CWD, а __DIR__ . /catalog.txt — рядом с данным исходником. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$before = posix_getcwd();
if ($before === false) throw new RuntimeException('Не определён CWD');
try {
if (!chdir(__DIR__)) throw new RuntimeException('chdir не выполнен');
echo 'Читаем относительно: ', posix_getcwd(), "\n";
} finally {
if (!chdir($before)) throw new RuntimeException('Не восстановлен CWD');
}
echo "Рабочий каталог восстановлен\n";
Ожидаемый результат
Путь скрипта, затем строка о восстановлении.
В библиотеке изменение CWD влияет на другой код процесса; абсолютные пути часто избавляют от этой скрытой зависимости. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_access, posix_get_last_error.
posix_mkfifoСоздать именованный канал для обмена байтами между своими локальными процессами.
PHP4+ · posix (Unix)
posix_mkfifo(string $filename, int $permissions): boolСоздать именованный канал для обмена байтами между своими локальными процессами.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_mkfifo(string $filename, int $permissions): bool |
| Вход | Новый путь; права, например 0600 в восьмеричной записи. Итоговый режим: permissions & ~umask. |
| Результат и отказ | true если узел FIFO создан, иначе false. Чтение/запись идут затем обычными stream функциями. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
FIFO — байтовый канал, не обычный файл хранения и не очередь с подтверждением. Открытие одного конца может блокироваться до второго; EOF/частичные чтения/записи требуют протокола. Для двустороннего разговора переносимее два FIFO либо Unix socket, а не обещание портативного r+.
<?php
declare(strict_types=1);
$dir = sys_get_temp_dir() . '/php-fifo-' . bin2hex(random_bytes(8));
if (!mkdir($dir, 0700)) throw new RuntimeException('Каталог не создан');
$path = $dir . '/events';
try {
if (!posix_mkfifo($path, 0600)) throw new RuntimeException('FIFO не создан');
echo filetype($path), "\n";
} finally {
if (file_exists($path)) unlink($path);
rmdir($dir);
}
Ожидаемый результат
fifo
Только собственный случайный каталог; не открываем канал, поэтому не ждём второго процесса. После удаления имени уже открытые дескрипторы у других участников жили бы по правилам ОС. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$dir = sys_get_temp_dir() . '/php-fifo-mode-' . bin2hex(random_bytes(8));
if (!mkdir($dir, 0700)) throw new RuntimeException('Каталог не создан');
$path = $dir . '/events';
$oldMask = umask(0077);
try {
if (!posix_mkfifo($path, 0666)) throw new RuntimeException('FIFO не создан');
clearstatcache(true, $path);
printf("Режим: %04o\n", fileperms($path) & 0777);
} finally {
umask($oldMask);
if (file_exists($path)) unlink($path);
rmdir($dir);
}
Ожидаемый результат
Режим: 0600
0666 & ~0077 оставляет чтение/запись владельцу. Десятичное666 — другое число. umask меняет окружение процесса и здесь восстановлен; это не готовый многопоточный шаблон. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_mknod, posix_fpathconf.
posix_mknodСоздать специальный файловый узел, когда системная интеграция действительно требует типа FIFO/устройства.
PHP5.1+ · posix (Unix)
posix_mknod(string $filename, int $flags, int $major = 0, int $minor = 0): boolСоздать специальный файловый узел, когда системная интеграция действительно требует типа FIFO/устройства.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_mknod(string $filename, int $flags, int $major = 0, int $minor = 0): bool |
| Вход | Новый путь; flags = один POSIX_S_IF* | права. major/minor — номера устройства для CHR/BLK, не длина файла. |
| Результат и отказ | true либо false; в PHP8.5 major0 для CHR/BLK вызывает ValueError. Доступность типов/создания зависит от ОС и прав. |
| Среда и версия | PHP5.1+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Обычный сайт не создаёт device nodes. Для обычного файла проще fopen с x; для FIFO понятнее mkfifo; socket endpoint создают socket_bind. Не копируем учебные примеры с world-writable устройствами. Указание S_IFSOCK не создаёт слушающий socket.
<?php
declare(strict_types=1);
$dir = sys_get_temp_dir() . '/php-node-' . bin2hex(random_bytes(8));
if (!mkdir($dir, 0700)) throw new RuntimeException('Каталог не создан');
$path = $dir . '/events';
try {
if (!posix_mknod($path, POSIX_S_IFIFO | 0600)) throw new RuntimeException('ОС отклонила mknod');
echo filetype($path), "\n";
} finally {
if (file_exists($path)) unlink($path);
rmdir($dir);
}
Ожидаемый результат
fifo на разрешающей это ОС либо исключение; устройство не создаётся.
Битовая маска описывает одновременно тип и доступ; major/minor здесь не используются. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$dir = sys_get_temp_dir() . '/php-node-file-' . bin2hex(random_bytes(8));
if (!mkdir($dir, 0700)) throw new RuntimeException('Каталог не создан');
$path = $dir . '/report';
try {
if (!posix_mknod($path, POSIX_S_IFREG | 0600)) throw new RuntimeException('Узел не создан');
echo filetype($path), ': ', filesize($path), "\n";
} finally {
if (file_exists($path)) unlink($path);
rmdir($dir);
}
Ожидаемый результат
file: 0 на поддерживающей ОС.
mknod создаёт узел, но не открывает stream и не записывает отчёт. В прикладном коде fopen($path, "x") объединяет создание с получением дескриптора. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_mkfifo, posix_access.
posix_isattyВыбрать формат CLI отчёта: удобный для человека в терминале или чистый текст при перенаправлении в файл.
PHP4+ · posix (Unix)
posix_isatty(resource|int $file_descriptor): boolВыбрать формат CLI отчёта: удобный для человека в терминале или чистый текст при перенаправлении в файл.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_isatty(resource|int $file_descriptor): bool |
| Вход | Открытый stream resource либо настоящий числовой fd. |
| Результат и отказ | true для терминала; false для обычного файла/pipe/невалидного fd. PHP8.5 предупреждает о недопустимом диапазоне; errno для плохого fd уточнён в8.4. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
false — часто нормальный результат перенаправления, не авария. TTY не обещает поддержку цвета/UTF-8. Для PHP stream часто достаточно stream_isatty без расширения POSIX.
ОС дескриптор — малое целое, например0/1/2 для stdin/stdout/stderr при обычном CLI запуске. PHP stream resource — другая сущность: передавайте сам STDOUT/$stream, не (int)$stream. Числовой ID PHP resource не обязан быть OS fd. Не каждый wrapper предоставляет настоящий дескриптор.
<?php
declare(strict_types=1);
echo posix_isatty(STDOUT) ? "Отчёт идёт в терминал\n" : "Отчёт идёт в файл или канал\n";
Ожидаемый результат
Результат зависит от перенаправления вывода.
php report.php и php report.php > report.txt дадут разные ветки без изменения кода. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$interactive = posix_isatty(STDOUT);
$items = [['sku' => 'A42', 'stock' => 7]];
if ($interactive) echo "Остатки каталога\n";
foreach ($items as $item) echo $item['sku'], ';', $item['stock'], "\n";
Ожидаемый результат
В терминале заголовок и A42;7; в pipe/файле только A42;7.
Не добавляем progress bar и управляющие коды к данным, которые получает следующая программа. Для общего CSV с кавычками используйте fputcsv. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_ttyname, posix_ctermid.
posix_ttynameУзнать конкретное терминальное устройство открытого потока при диагностике CLI.
PHP4+ · posix (Unix)
posix_ttyname(resource|int $file_descriptor): string|falseУзнать конкретное терминальное устройство открытого потока при диагностике CLI.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_ttyname(resource|int $file_descriptor): string|false |
| Вход | Stream или OS fd. |
| Результат и отказ | Абсолютный путь терминала либо false. Неверные integer fd дают warning с8.3; с8.5 stored errno устанавливается EBADF. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Путь может быть /dev/pts/N, но не надо конструировать его вручную. Возвращённая строка не открывает устройство и не обещает, что оно останется тем же.
ОС дескриптор — малое целое, например0/1/2 для stdin/stdout/stderr при обычном CLI запуске. PHP stream resource — другая сущность: передавайте сам STDOUT/$stream, не (int)$stream. Числовой ID PHP resource не обязан быть OS fd. Не каждый wrapper предоставляет настоящий дескриптор.
<?php
declare(strict_types=1);
$terminal = posix_ttyname(STDOUT);
echo $terminal === false ? "STDOUT не имеет имени терминала\n" : "Терминал: $terminal\n";
Ожидаемый результат
Путь терминала либо сообщение о его отсутствии.
При перенаправлении вывода отсутствие terminal name нормально. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
foreach (['stdin' => STDIN, 'stdout' => STDOUT] as $name => $stream) {
if (!posix_isatty($stream)) {
echo "$name: не терминал\n";
continue;
}
$terminal = posix_ttyname($stream);
echo $name, ': ', $terminal === false ? 'имя недоступно' : $terminal, "\n";
}
Ожидаемый результат
Две строки о stdin/stdout; один может быть терминалом, другой — файлом.
Например CLI утилита может читать клавиатуру, а результат отправлять в файл. Проверяем каждый поток отдельно. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_isatty, posix_ctermid.
posix_ctermidПолучить системный путь к управляющему терминалу процесса, отличая его от конкретного устройства STDOUT.
PHP4+ · posix (Unix)
posix_ctermid(): string|falseПолучить системный путь к управляющему терминалу процесса, отличая его от конкретного устройства STDOUT.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_ctermid(): string|false |
| Вход | Нет. |
| Результат и отказ | Путь строкой либо false; возможна пустая строка по поведению libc, её также обрабатываем. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
На Linux часто получается /dev/tty — общее имя обращения к своему controlling terminal. Наличие строки не доказывает, что процесс имеет терминал: cron может не иметь его и открытие пути откажет. Не сравнивайте строку с ttyname как уникальный ID.
<?php
declare(strict_types=1);
$path = posix_ctermid();
echo $path === false || $path === '' ? "Путь не получен\n" : "Controlling terminal path: $path\n";
Ожидаемый результат
Путь вроде /dev/tty либо сообщение об отсутствии.
Никакого чтения клавиатуры не происходит; программа только получает имя. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$controlling = posix_ctermid();
$output = posix_ttyname(STDOUT);
echo 'Controlling path: ', $controlling === false || $controlling === '' ? '(нет)' : $controlling, "\n";
echo 'STDOUT device: ', $output === false ? '(не терминал)' : $output, "\n";
Ожидаемый результат
Две строки; при перенаправлении stdout его terminal name может отсутствовать, хотя общий путь ctermid есть.
Так объясняется, почему нельзя решать интерактивность только по ctermid; для конкретного потока используйте isatty. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_ttyname, posix_isatty, posix_setsid.
posix_unameДобавить сведения о среде в локальный диагностический отчёт, когда один и тот же worker ведёт себя по-разному на двух серверах.
PHP4+ · posix (Unix)
posix_uname(): array|falseДобавить сведения о среде в локальный диагностический отчёт, когда один и тот же worker ведёт себя по-разному на двух серверах.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_uname(): array|false |
| Вход | Нет. |
| Результат и отказ | Массив строк sysname, nodename, release, version, machine; необязательный GNU domainname; false при отказе. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Не предполагайте формат release из трёх чисел и не используйте строку версии как единственную проверку возможностей. GNU domainname относится к NIS/YP, а не гарантированно к DNS домену сайта. Не публикуйте весь отчёт посетителям.
| Поле | Что узнаём |
|---|---|
| sysname | Семейство ОС, например Linux. |
| nodename | Сетевое имя узла в системном контексте; контейнер может иметь своё. |
| release | Выпуск ядра/ОС, формат не задан PHP. |
| version | Дополнительная информация о сборке. |
| machine | Аппаратная архитектура в представлении ОС. |
| domainname | Необязательное GNU расширение; не адрес веб-сайта. |
<?php
declare(strict_types=1);
$system = posix_uname();
if ($system === false) throw new RuntimeException('Данные ОС недоступны');
echo $system['sysname'], ' / ', $system['machine'], "\n";
Ожидаемый результат
Например Linux / x86_64; точные строки задаёт ОС.
Возвращается массив: квадратные скобки выбирают конкретное поле. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$system = posix_uname();
if ($system === false) throw new RuntimeException('uname не выполнен');
$report = ['os' => $system['sysname'], 'release' => $system['release'], 'php' => PHP_VERSION];
$report['nis_domain'] = $system['domainname'] ?? '(поле отсутствует)';
echo json_encode($report, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES), "\n";
Ожидаемый результат
JSON с ОС, выпуском, PHP и NIS полем/маркером отсутствия.
?? предотвращает предположение, что GNU поле есть в каждой сборке. Для реальной возможности проверяйте нужную функцию/константу. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_sysconf.
posix_timesОтделить потраченное процессором время обработки каталога от времени ожидания сети или диска.
PHP4+ · posix (Unix)
posix_times(): array|falseОтделить потраченное процессором время обработки каталога от времени ожидания сети или диска.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_times(): array|false |
| Вход | Нет. |
| Результат и отказ | Массив целых clock ticks: ticks, utime, stime, cutime, cstime; false при системном отказе. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это не наносекунды и не готовые секунды. cutime/cstime в системном times — накопленное CPU время завершённых и подождённых детей, а не сумма текущего процесса с детьми. ticks имеет платформенную точку отсчёта; не выдавайте его за переносимый uptime. Возможны переполнения/отрицательные значения.
| Поле | Смысл |
|---|---|
| utime | CPU время своего процесса в пользовательском режиме. |
| stime | CPU время ядра от имени своего процесса. |
| cutime/cstime | Учтённое время детей после соответствующего ожидания; не текущий родитель ещё раз. |
| ticks | Системный счётчик times с платформенной эпохой. Для интервалов реального времени используйте hrtime. |
<?php
declare(strict_types=1);
$times = posix_times();
if ($times === false) throw new RuntimeException('CPU счётчики недоступны');
echo 'User ticks: ', $times['utime'], '; system ticks: ', $times['stime'], "\n";
Ожидаемый результат
Два числовых счётчика, в коротком процессе могут быть0.
Маленькая задача может быть короче одного системного тика, и ноль не означает, что код не исполнялся. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (!defined('POSIX_SC_CLK_TCK')) throw new RuntimeException('Нужна поддержка POSIX_SC_CLK_TCK, PHP8.4+');
$hz = posix_sysconf(POSIX_SC_CLK_TCK);
$before = posix_times();
if ($hz <= 0 || $before === false) throw new RuntimeException('Нет корректных счётчиков');
$digest = '';
for ($i = 0; $i < 10000; $i++) $digest = hash('sha256', 'catalog-' . $i);
$after = posix_times();
if ($after === false) throw new RuntimeException('Не прочитан итог');
$ticks = ($after['utime'] - $before['utime']) + ($after['stime'] - $before['stime']);
if ($ticks < 0) throw new RuntimeException('Счётчик переполнился или изменился');
printf("CPU seconds: %.6f\n", $ticks / $hz);
Ожидаемый результат
Неотрицательное измерение CPU секунд, возможно0 на быстрой машине.
Не зашиваем100 ticks/s; узнаём частоту ОС. Это одно измерение конкретного участка, не универсальный рейтинг быстродействия PHP. Для latency API нужны отдельные wall-clock интервалы. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_sysconf, posix_getrlimit.
posix_getrlimitПонять отказ открытия новых файлов или запуска задач до того, как увеличивать PHP memory_limit наугад.
PHP4+ · posix (Unix)
posix_getrlimit(?int $resource = null): array|falseПонять отказ открытия новых файлов или запуска задач до того, как увеличивать PHP memory_limit наугад.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_getrlimit(?int $resource = null): array|false |
| Вход | null/без аргумента — набор именованных лимитов; с PHP8.3 можно передать POSIX_RLIMIT_* для одного ресурса. |
| Результат и отказ | Общий набор содержит ключи soft X/hard X. Один ресурс в tagged PHP8.5 возвращает [0 => soft, 1 => hard]. Значения int или строка "unlimited"; false при отказе. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Soft — действующая граница; hard — потолок, до которого обычный процесс может поднять soft. Снижение hard для обычного процесса необратимо. Набор без аргумента ограничен таблицей wrapper, не обязательно включает все доступные RLIMIT_*; отдельный ресурс запросите явно.
Имена общего массива: core, data, stack, virtualmem, totalmem, rss, maxproc, memlock, cpu, filesize, openfiles, а на соответствующих системах kqueues/npts. Есть только поддерживаемые ключи. filesize — размер файла, не data segment; cpu — CPU секунды; openfiles — граница дескрипторов. Полная таблица единиц и ресурсов отделяет память процесса от PHP memory_limit.
<?php
declare(strict_types=1);
$limits = posix_getrlimit();
if ($limits === false) throw new RuntimeException('Лимиты недоступны');
echo 'Soft openfiles: ', $limits['soft openfiles'] ?? '(нет ключа)', "\n";
echo 'Hard openfiles: ', $limits['hard openfiles'] ?? '(нет ключа)', "\n";
Ожидаемый результат
Два лимита или маркеры отсутствующего ключа.
Служба наследует лимиты launcher/supervisor; значения интерактивной shell могут быть другими. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$limits = posix_getrlimit(POSIX_RLIMIT_NOFILE);
if ($limits === false) throw new RuntimeException('NOFILE недоступен');
[$soft, $hard] = $limits;
echo 'Soft=', $soft, '; hard=', $hard, "\n";
if (is_int($soft) && $soft < 128) echo "Мало дескрипторов для проекта с большим числом соединений\n";
Ожидаемый результат
Soft/hard и дополнительное сообщение для числового soft<128.
Строку unlimited не преобразуем в0. Выбор128 — политика учебного проекта, а не универсальный минимум для PHP. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_setrlimit, posix_sysconf.
posix_setrlimitОграничить конкретный одноразовый обработчик системным ресурсом, не меняя общую конфигурацию всех процессов.
PHP7+ · posix (Unix)
posix_setrlimit(int $resource, int $soft_limit, int $hard_limit): boolОграничить конкретный одноразовый обработчик системным ресурсом, не меняя общую конфигурацию всех процессов.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_setrlimit(int $resource, int $soft_limit, int $hard_limit): bool |
| Вход | Ресурс POSIX_RLIMIT_*; soft/hard в единицах именно ресурса, либо POSIX_RLIMIT_INFINITY. |
| Результат и отказ | true или false при отказе ОС. PHP8.5 ValueError при значении ниже-1 и обычном finite soft>hard; несовместимость infinity и конечного hard тоже обрабатывайте как отказ. |
| Среда и версия | PHP7+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Не переносите строку "unlimited" из getrlimit в int аргумент: используйте символическую константу. Не снижайте hard без намерения; обычно оставляйте существующий hard. Лимиты наследуют дети. CPU limit не заменяет сетевой timeout; память ОС отличается от memory_limit.
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') throw new RuntimeException('Нужен отдельный CLI');
$limits = posix_getrlimit(POSIX_RLIMIT_CORE);
if ($limits === false) throw new RuntimeException('Не прочитан CORE');
$hard = $limits[1] === 'unlimited' ? POSIX_RLIMIT_INFINITY : $limits[1];
if (!posix_setrlimit(POSIX_RLIMIT_CORE, 0, $hard)) throw new RuntimeException('Лимит не принят');
echo "Soft CORE=0, hard сохранён\n";
Ожидаемый результат
Soft CORE=0, hard сохранён.
Изменяем soft в разрешённых пределах. Это не включает шифрование секретов и не отменяет все внешние механизмы сборщика crash dumps; показываем именно RLIMIT_CORE. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (PHP_VERSION_ID < 80500) throw new RuntimeException('Урок рассчитан на PHP8.5');
try {
posix_setrlimit(POSIX_RLIMIT_CORE, -2, 0);
} catch (ValueError $error) {
echo "Значение -2 не является корректным лимитом\n";
}
Ожидаемый результат
Значение -2 не является корректным лимитом.
Этот неверный аргумент отвергается до изменения лимита. Для безграничного значения есть POSIX_RLIMIT_INFINITY, не произвольное отрицательное число. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_getrlimit, posix_get_last_error.
posix_sysconfУзнать параметры ОС, нужные для расчёта размеров и настройки числа фоновых обработчиков.
PHP8.3+ · posix (Unix)
posix_sysconf(int $conf_id): intУзнать параметры ОС, нужные для расчёта размеров и настройки числа фоновых обработчиков.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_sysconf(int $conf_id): int |
| Вход | Одна POSIX_SC_* константа из полной таблицы. |
| Результат и отказ | Числовое значение; -1 может означать неопределённый предел, отсутствие поддержки или ошибку. |
| Среда и версия | PHP8.3+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Wrapper PHP8.5 возвращает sysconf напрямую, не обновляя POSIX last_error. По старому errno нельзя различить эти случаи. Проверяйте допустимость значения для своей задачи и используйте явно выбранный fallback. Число online CPU не равно quota контейнера или оптимальному числу HTTP запросов.
<?php
declare(strict_types=1);
$bytes = posix_sysconf(POSIX_SC_PAGESIZE);
if ($bytes <= 0) throw new RuntimeException('Размер страницы не определён');
echo 'Страница ОС: ', $bytes, " байт\n";
Ожидаемый результат
Например Страница ОС: 4096 байт.
Это страница памяти ядра, не HTML страница и не размер PHP массива. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$online = posix_sysconf(POSIX_SC_NPROCESSORS_ONLN);
$configuredMaximum = 4;
$workers = $online > 0 ? min($online, $configuredMaximum) : 1;
echo 'Предварительный предел worker: ', $workers, "\n";
Ожидаемый результат
Число от1 до4.
CPU значение — только стартовый ориентир. Дополнительно учитывают container quota, RAM на задачу, лимиты API и измерение latency; автоматическое создание N процессов здесь не происходит. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_times, posix_pathconf, posix_getrlimit.
posix_pathconfПроверить предел имени файла на той файловой системе, куда сохраняется экспорт.
PHP8.3+ · posix (Unix)
posix_pathconf(string $path, int $name): int|falseПроверить предел имени файла на той файловой системе, куда сохраняется экспорт.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_pathconf(string $path, int $name): int|false |
| Вход | Непустой путь; name — POSIX_PC_* селектор. Для NAME_MAX передайте каталог будущего файла. |
| Результат и отказ | Числовой предел/признак либо false; пустой путь вызывает ValueError, open_basedir может дать warning и false. |
| Среда и версия | PHP8.3+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
NAME_MAX — длина одного компонента в байтах. PATH_MAX — иной предел; не считайте число «символами русского текста» и не пытайтесь исправить доступ одной проверкой длины.
pathconf/fpathconf относятся к конкретному объекту/файловой системе: лимит одного mount не обязательно подходит другому. В libc значение-1 при errno0 означает неопределённый предел. Tagged PHP8.5 wrapper проверяет errno после вызова, но предварительно его не обнуляет; поэтому при -1 возможна неоднозначность со старым системным errno. Для прикладной политики и false, и отрицательное значение трактуем как «надёжного положительного лимита нет», не как нулевой разрешённый размер.
<?php
declare(strict_types=1);
$limit = posix_pathconf(__DIR__, POSIX_PC_NAME_MAX);
echo is_int($limit) && $limit > 0 ? "NAME_MAX=$limit байт\n" : "Предел имени не определён\n";
Ожидаемый результат
Положительный предел в байтах либо явное неизвестное значение.
Спрашиваем каталог, а не ещё не существующий полный путь файла. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$directory = __DIR__;
$name = 'catalog-2026-10.csv';
$limit = posix_pathconf($directory, POSIX_PC_NAME_MAX);
if (!is_int($limit) || $limit <= 0) throw new RuntimeException('Лимит не определён, нужна политика приложения');
if (strlen($name) > $limit) throw new RuntimeException('Имя слишком длинное');
echo "Имя помещается в предел компонента\n";
Ожидаемый результат
Имя помещается в предел компонента при достаточном положительном лимите.
Это проверка одного требования. Права, свободное место, зарезервированные имена и race при создании ещё проверяются фактическим fopen. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_fpathconf, posix_sysconf.
posix_fpathconfПрочитать системный предел через уже открытый дескриптор вместо повторного разрешения пути.
PHP8.3+ · posix (Unix)
posix_fpathconf(resource|int $file_descriptor, int $name): int|falseПрочитать системный предел через уже открытый дескриптор вместо повторного разрешения пути.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_fpathconf(resource|int $file_descriptor, int $name): int|false |
| Вход | Открытый stream/настоящий OS fd; POSIX_PC_* селектор. Нельзя подставлять integer ID PHP resource. |
| Результат и отказ | Числовой предел/признак либо false. Невалидный resource может вызвать ValueError; PHP8.5 плохой fd сопровождает warning/EBADF. |
| Среда и версия | PHP8.3+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Открытый дескриптор привязан к открытому объекту, даже если имя позднее изменилось. Это полезное отличие от pathconf, но не резервирование свободного места и не блокировка.
pathconf/fpathconf относятся к конкретному объекту/файловой системе: лимит одного mount не обязательно подходит другому. В libc значение-1 при errno0 означает неопределённый предел. Tagged PHP8.5 wrapper проверяет errno после вызова, но предварительно его не обнуляет; поэтому при -1 возможна неоднозначность со старым системным errno. Для прикладной политики и false, и отрицательное значение трактуем как «надёжного положительного лимита нет», не как нулевой разрешённый размер.
<?php
declare(strict_types=1);
$stream = fopen(__DIR__ . '/catalog.txt', 'rb');
if ($stream === false) throw new RuntimeException('Файл не открыт');
try {
$limit = posix_fpathconf($stream, POSIX_PC_NAME_MAX);
echo is_int($limit) && $limit > 0 ? "NAME_MAX=$limit\n" : "Предел не определён\n";
} finally { fclose($stream); }
Ожидаемый результат
Предел NAME_MAX либо сообщение об отсутствии достоверного значения.
В функцию передан сам $stream. Закрытие в finally освобождает дескриптор независимо от результата. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
if (posix_isatty(STDOUT)) throw new RuntimeException('Запустите пример с перенаправлением в pipe');
$limit = posix_fpathconf(STDOUT, POSIX_PC_PIPE_BUF);
$record = "A42;7\n";
if (!is_int($limit) || $limit <= 0) throw new RuntimeException('PIPE_BUF не определён');
echo strlen($record) <= $limit ? "Запись укладывается в PIPE_BUF\n" : "Запись превышает PIPE_BUF\n";
Ожидаемый результат
При stdout в pipe и достаточном лимите — Запись укладывается в PIPE_BUF.
PIPE_BUF ограничивает атомарность отдельного системного write в pipe, а не общую ёмкость канала. PHP stream buffering/частичные fwrite не превращаются автоматически в гарантию одного syscall. Проверка isattyfalse сама по себе также не доказывает pipe; это явная предпосылка запуска. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_pathconf, posix_mkfifo, posix_isatty.
posix_get_last_errorСохранить номер отказа POSIX сразу после операции, чтобы журнал объяснил причину.
PHP4+ · posix (Unix)
posix_get_last_error(): intСохранить номер отказа POSIX сразу после операции, чтобы журнал объяснил причину.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_get_last_error(): int |
| Вход | Нет. |
| Результат и отказ | Сохранённое целое errno; начальное0, затем последний записанный wrapper код. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Числовые значения errno зависят от ОС. Не зашивайте2/13 как универсальные ENOENT/EACCES; текст зависит от libc и локали. Код нужен диагностике, результат функции — управлению.
Сначала проверяем результат конкретной операции, только затем читаем код. Сохранённая POSIX ошибка не сбрасывается каждой успешной операцией и не обновляется каждым wrapper. В частности, sysconf, setsid и initgroups нельзя диагностировать по старому коду так, будто он точно относится к последнему вызову. Для файловых stream ошибок есть своя диагностика, не POSIX errno.
<?php
declare(strict_types=1);
$path = __DIR__ . '/missing-' . bin2hex(random_bytes(8));
if (!posix_access($path, POSIX_F_OK)) {
$error = posix_get_last_error();
echo 'Отказ: ', $error, ' ', posix_strerror($error), "\n";
}
Ожидаемый результат
Строка с кодом/текстом отказа для отсутствующего пути.
Ничего не создаём и не удаляем; запоминаем errno до любой другой POSIX операции. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$path = __DIR__ . '/missing-' . bin2hex(random_bytes(8));
if (!posix_access($path, POSIX_R_OK)) {
$captured = posix_get_last_error();
$pid = posix_getpid();
echo json_encode(['pid' => $pid, 'operation' => 'access', 'errno' => $captured,
'message' => posix_strerror($captured)], JSON_THROW_ON_ERROR), "\n";
}
Ожидаемый результат
Одна JSON строка с сохранённым errno и PID.
Не включаем в публичный ответ внутренние пути/детали ОС. Следующий успех не является способом «очистить ошибку». Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_errno, posix_strerror, posix_access.
posix_errnoПрочитать тот же POSIX код ошибки под коротким историческим именем.
PHP4+ · posix (Unix)
posix_errno(): intПрочитать тот же POSIX код ошибки под коротким историческим именем.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_errno(): int |
| Вход | Нет. |
| Результат и отказ | Тот же результат, что posix_get_last_error; это alias. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Это не отдельная очередь ошибок, не код последнего HTTP ответа и не errno всех расширений PHP. В новом коде длинное имя часто понятнее читателю.
Сначала проверяем результат конкретной операции, только затем читаем код. Сохранённая POSIX ошибка не сбрасывается каждой успешной операцией и не обновляется каждым wrapper. В частности, sysconf, setsid и initgroups нельзя диагностировать по старому коду так, будто он точно относится к последнему вызову. Для файловых stream ошибок есть своя диагностика, не POSIX errno.
<?php
declare(strict_types=1);
posix_access(__DIR__ . '/missing-' . bin2hex(random_bytes(8)), POSIX_F_OK);
$short = posix_errno();
$long = posix_get_last_error();
echo $short === $long ? "Оба имени читают один код\n" : "Код изменился\n";
Ожидаемый результат
Оба имени читают один код.
Это чтение одного сохранённого значения, а не две независимые проверки файла. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$ok = posix_access(__DIR__, POSIX_R_OK | POSIX_X_OK);
if ($ok) {
echo "Каталог доступен\n";
} else {
$error = posix_errno();
echo 'Доступ не подтверждён: ', posix_strerror($error), "\n";
}
Ожидаемый результат
Сообщение об успехе либо текст отказа.
После успеха не читаем старую ошибку, чтобы не создать ложную тревогу. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_get_last_error, posix_strerror.
posix_strerrorПревратить сохранённый системный код в понятную строку локального журнала.
PHP4+ · posix (Unix)
posix_strerror(int $error_code): stringПревратить сохранённый системный код в понятную строку локального журнала.
| Часть вызова | Объяснение |
|---|---|
| Сигнатура | posix_strerror(int $error_code): string |
| Вход | Целый errno, обычно только что сохранённый posix_get_last_error. |
| Результат и отказ | Строка libc. Неизвестный код обычно тоже представлен строкой; точный язык/формат не фиксирован. |
| Среда и версия | PHP4+; расширение POSIX на Unix. Наличие конкретного API проверяют function_exists, константы — defined. |
Текст полезен человеку, но сравнение строк "Permission denied" — хрупкая бизнес-логика. Сам вызов не повторяет операцию и не устраняет отказ.
<?php
declare(strict_types=1);
echo posix_strerror(0), "\n";
Ожидаемый результат
Системная строка для кода0, например Success; зависит от libc/локали.
Передали0 — получили его описание. Это не проверка успешности предыдущего запроса. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
<?php
declare(strict_types=1);
$path = __DIR__ . '/missing-' . bin2hex(random_bytes(8));
if (posix_access($path, POSIX_F_OK) === false) {
$number = posix_get_last_error();
$description = posix_strerror($number);
echo 'POSIX ', $number, ': ', $description, "\n";
}
Ожидаемый результат
Код и текст ошибки отсутствующего пути.
Число позволяет сопоставлять записи на одном стенде; человек читает описание. Для принятия решения сохраняем отдельный факт отказа access. Контекст: отдельный Unix CLI процесс с расширением POSIX; числовые ID, пути и системные сообщения зависят от стенда. Проверен PHP синтаксис, а не выполнение POSIX на Windows. Изменения прав/лимитов предназначены только для одноразового учебного процесса.
Связанные действия: posix_get_last_error, posix_errno.
Источники и обсуждения
Код и руководство с собой
Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.
Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.
Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


