Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

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

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 125 · От первого результата к полному официальному справочнику

Miscellaneous: полный справочник разных функций PHP

Все 37 узлов официальной ветки: 31 функция и шесть структурных страниц — от первой понятной задачи до полного договора, ошибок, версий, SAPI и платформы.

Разные функции PHP: почему они собраны вместе и с чего начать

Miscellaneous — официальный раздел для функций, которым не подошла другая категория. Это не один API: здесь рядом находятся управление завершением сценария, паузы, двоичные данные, подсветка исходника, состояние HTTP-соединения и Windows-консоль. Поэтому начинать надо с задачи, а не читать список как последовательный урок.

Если нужноОткройтеЧто получите
Остановить CLI/HTTP-сценарийexitСтроковое сообщение либо целый код; границы shutdown/finally.
Сделать короткую паузуsleep, usleep, time_nanosleepЯвные единицы, результат и платформенные границы.
Собрать/разобрать бинарный протоколpack / unpackБайты, формат, длину и порядок endian.
Понять уход HTTP-клиентаconnection_aborted / connection_statusНаблюдаемое состояние после реальной записи, а не магическую отмену.
Сгенерировать идентификаторuniqidГраницы time-based ID и безопасная альтернатива для секретов.
Работать с Windows-консольюsapi_windows_cp_getОтдельный Windows-only маршрут с реальными проверками.
Вызвать Python, Node.js или другую программуexec, system, shell_exec, passthru и proc_openРаздельные stdout/stderr/exit code, безопасный argv и лимиты процесса.

Установка и доступность: Core, Standard, SAPI и операционная система

Для основных функций отдельная установка не нужна: они входят в PHP. Но наличие имени ещё не означает одинаковое поведение везде. SAPI — способ запуска PHP: CLI, встроенный сервер, FPM, Apache-модуль и другие. Функции соединения имеют смысл в HTTP-SAPI, sys_getloadavg отсутствует в Windows, а sapi_windows_* существуют только в Windows-сборке.

ГруппаГде проверятьЧестная граница
Core/Standardfunction_exists + версия PHPСемантика могла меняться; смотрите changelog карточки.
connection_* / ignore_user_abortИзолированный localhost HTTPCLI показывает тип, но не эмулирует уход браузера.
sapi_windows_*Отдельный Windows-процесс/консольНа Linux/macOS функции отсутствуют; это не ошибка переносимого кода.
sys_getloadavgUnix-хост и function_existsWindows-результат нельзя подделывать числом.
get_browserНастроенный browscapБез внешней базы возможностей функция выдаёт предупреждение/false.

Проверка синтаксиса не доказывает работу HTTP, консоли или внешнего browscap. В примерах явно указано, что было реально выполнено, что проверено только на Windows и что остаётся контекстным фрагментом.

Runtime-настройки: что меняет поведение функций

Официальная ветка задаёт следующие INI-настройки. INI_SYSTEM обычно задаётся администратором сервера; менять её посреди запроса нельзя. Цвета подсветки формируют HTML и не делают просмотр исходника безопасным.

НастройкаDefaultУровеньВлияние и практическая проверка
ignore_user_abort"0"INI_ALLПродолжать ли после обнаруженного disconnect. Функция ignore_user_abort читает/меняет режим для текущего выполнения.
highlight.string"#DD0000"INI_ALLЦвет строк в HTML, который создают highlight_file/highlight_string.
highlight.comment"#FF8000"INI_ALLЦвет комментариев.
highlight.keyword"#007700"INI_ALLЦвет ключевых слов.
highlight.default"#0000BB"INI_ALLЦвет обычного текста PHP-кода.
highlight.html"#000000"INI_ALLЦвет HTML вне PHP-тегов.
highlight.bg—только в описании страницыУпоминается ниже официальной таблицы, но отсутствует в её современном перечне options; не проектируйте переносимый код вокруг этой строки.
browscapNULLINI_SYSTEMПуть к browser capabilities file для get_browser. База внешняя, требует обновления и доверенной поставки.

Сначала читайте эффективное значение через ini_get и фиксируйте конфигурацию рядом с окружением. Не полагайтесь на php.ini локальной машины как на доказательство настройки production FPM.

Предопределённые константы: состояния соединения и смещение payload

Три CONNECTION_* значения кодируют состояние соединения. NORMAL равен нулю, ABORTED и TIMEOUT — независимые биты; поэтому комбинированное состояние читают побитовой операцией &, а не одним равенством.

КонстантаКогда существуетСмысл
CONNECTION_NORMALВсегда в расширенииНормальное состояние; значение 0.
CONNECTION_ABORTEDВсегда в расширенииБит 1: клиентский разрыв был обнаружен.
CONNECTION_TIMEOUTВсегда в расширенииБит 2: достигнут тайм-аут соединения/сценария.
__COMPILER_HALT_OFFSET__Только в файле, где вызван __halt_compiler()Байтовое смещение первого байта после остановки компилятора.

Константа halt имеет смысл вместе с __halt_compiler; в другом файле проверяйте defined и не угадывайте offset по длине строки. Практический декодер маски показан в connection_status.

Вызов другого языка: где заканчивается Miscellaneous

Глобальные exec(), system(), shell_exec() и passthru() легко принять за «разные функции». В официальном PHP Manual это отдельная ветка System Program Execution. Здесь мы ставим явную границу, чтобы читатель не спутал eval() с запуском отдельной программы, а глобальную exec() — с PDO::exec() или curl_exec().

ИнструментЧто получает PHPКогда выбирать
exec()Массив строк stdout, последнюю строку и отдельный exit code.Короткий текстовый отчёт, где важно отличить текст от кода завершения.
system()Сразу печатает stdout; return содержит только последнюю строку.Доверенный построчный CLI-отчёт; в HTTP нужно учитывать все уровни буферизации.
shell_exec()Весь stdout одной строкой, но без отдельного exit code.Только когда нет бизнес-решения по успеху: null не различает пустой успех и ряд ошибок.
passthru()Печатает сырые bytes; результат не возвращается строкой.Доверенный бинарный вывод; до HTTP-тела задают Content-Type, а для атомарного ответа сначала проверяют весь результат.
proc_open()Отдельные stdin/stdout/stderr, argv, cwd, environment и resource процесса.Интеграция с Python/Node/C, где нужны JSON, диагностика, deadline и проверка схемы.

Полный путь данных разобран в практической главе о PHP, Python и Node.js: PHP формирует проверенный JSON, запускает фиксированный worker, читает stdout/stderr, проверяет exit code, декодирует JSON и проверяет типы до публикации результата.

Полный справочник Miscellaneous: 31 функция по задачам

Это полный официальный список текущей ветки book.misc. Каждый пункт ведёт к одному каноническому якорю; прежние карточки constant/define/defined и функций времени не дублируются.

Управление выполнением и HTTP

Время, ожидание и нагрузка

Двоичные строки и контейнер в файле

Константы и динамическое имя

Capabilities и исходный код

Windows SAPI

Идентификаторы

Changelog официального раздела: изменения, которые меняют код

ВерсияФункцияИзменение
8.5.0hrtimemacOS использует CLOCK_UPTIME_RAW вместо mach_absolute_time.
8.4.0exitСтал proper function: обычные типы/strict_types, named argument и variable function.
8.4.0exitПараметрless exit в shutdown/destructor сбрасывает прежний exit code в 0.
8.4.0highlight_stringВозврат уточнён с string|bool до string|true.
8.3.0highlight_file / highlight_stringИзменился генерируемый HTML.
8.1.0defineЗначение может быть объектом.
8.0.0constantНеизвестное имя теперь бросает Error вместо E_WARNING + null.
8.0.0definecase_insensitive=true вызывает E_WARNING; false ещё принимается.
8.0.0ignore_user_abortenable стал nullable.
8.0.0packБольше не возвращает false при ошибке.
8.0.0sapi_windows_vt100_supportenable стал nullable.
8.0.0sleepОтрицательные seconds бросают ValueError вместо warning + false.
7.3.0definecase_insensitive deprecated перед удалением поддержки.
7.2.0pack / unpackFloat/double получили явный big/little endian.
7.1.1 / 7.0.15packДобавлены e/E/g/G для byte order float/double.
7.1.0unpackДобавлен необязательный offset.

Таблица воспроизводит все строки официальной страницы changelog.misc по зафиксированному снимку. Подробное следствие и рабочий пример находятся в соответствующей карточке.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

connection_abortedПроверить, обнаружил ли текущий SAPI отключение клиента.

PHP 4+ · standard

connection_aborted(): int

Проверить, обнаружил ли текущий SAPI отключение клиента.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

HTTP-клиент ушёл
  1. Код формирует очередную порцию
  2. SAPI пытается отправить её через буферы/сервер
  3. Разрыв становится наблюдаемым
  4. connection_aborted возвращает 1

Первый запуск и развитие задачи

Увидеть нормальное соединение в CLIСамостоятельный пример
<?php
$status = connection_status();
echo $status === CONNECTION_NORMAL ? "normal\n" : "other\n";
echo connection_aborted() === 0 ? "connected\n" : "aborted\n";
Ожидаемый результат
normal
connected

CLI-процесс не обслуживает браузерное соединение, поэтому это только минимальная проверка типов и исходного состояния. Настоящий disconnect проверяется отдельным локальным HTTP-опытом.

Локальный HTTP-опыт: клиент закрывает сокетФрагмент или команда
<?php
// endpoint.php — только для отдельного localhost-теста.
ignore_user_abort(true);
while (ob_get_level() > 0) { ob_end_flush(); }
header('Content-Type: text/plain');
for ($part = 1; $part <= 200; $part++) {
    echo str_repeat('x', 65536);
    flush();
    if (connection_aborted()) {
        file_put_contents(__DIR__ . '/observed.txt',
            connection_status() . "\n", LOCK_EX);
        break;
    }
    usleep(10000);
}

Запускайте файл отдельным php -S на 127.0.0.1, подключайте локальный сокет, прочитайте начало ответа и закройте клиент. Проверенная harness-процедура хранится в evidence/misc-connection-http-test.py. Буферы, веб-сервер и прокси влияют на момент обнаружения; это фрагмент, а не обещание боевого SAPI.

Не стройте бесконечный цикл ожидания disconnect. Работа должна иметь собственный deadline, отмену и идемпотентность; долгие задания выносите из HTTP в очередь.

Полный договор вызова

Часть вызоваПолный договор
ПараметрыНет.
Возврат1 после обнаруженного отключения, иначе 0. Это int, хотя условие if принимает его как boolean.
Момент обнаруженияОбычно после попытки реально отправить данные; echo без доставки через буферы не гарантирует обновление состояния.

Ошибки и границы. Функция сообщает состояние соединения, а не причину остановки процесса. Тайм-аут, исключение и завершение воркера требуют отдельных сигналов.

Версии и платформа. Реальное обнаружение зависит от SAPI, веб-сервера, reverse proxy, буферов и момента записи.

Рядом: connection_status, ignore_user_abort.

Карта полного раздела Miscellaneous.

connection_statusПолучить битовую маску состояния текущего клиентского соединения.

PHP 4+ · standard

connection_status(): int

Получить битовую маску состояния текущего клиентского соединения.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Одно число → несколько признаков
  1. Получить status
  2. Проверить бит ABORTED
  3. Проверить бит TIMEOUT
  4. Собрать решение по обоим признакам

Первый запуск и развитие задачи

Разобрать битовую маску без путаницы с равенствомСамостоятельный пример
<?php
function connectionLabels(int $status): array
{
    $labels = [];
    if (($status & CONNECTION_ABORTED) !== 0) { $labels[] = 'aborted'; }
    if (($status & CONNECTION_TIMEOUT) !== 0) { $labels[] = 'timeout'; }
    return $labels === [] ? ['normal'] : $labels;
}
foreach ([CONNECTION_NORMAL, CONNECTION_ABORTED,
          CONNECTION_ABORTED | CONNECTION_TIMEOUT] as $status) {
    echo implode('+', connectionLabels($status)), "\n";
}
Ожидаемый результат
normal
aborted
aborted+timeout

CONNECTION_NORMAL равен нулю, а остальные состояния — биты. Проверка status === CONNECTION_ABORTED потеряла бы второй признак в комбинированном состоянии.

Локальный HTTP-опыт: клиент закрывает сокетФрагмент или команда
<?php
// endpoint.php — только для отдельного localhost-теста.
ignore_user_abort(true);
while (ob_get_level() > 0) { ob_end_flush(); }
header('Content-Type: text/plain');
for ($part = 1; $part <= 200; $part++) {
    echo str_repeat('x', 65536);
    flush();
    if (connection_aborted()) {
        file_put_contents(__DIR__ . '/observed.txt',
            connection_status() . "\n", LOCK_EX);
        break;
    }
    usleep(10000);
}

Запускайте файл отдельным php -S на 127.0.0.1, подключайте локальный сокет, прочитайте начало ответа и закройте клиент. Проверенная harness-процедура хранится в evidence/misc-connection-http-test.py. Буферы, веб-сервер и прокси влияют на момент обнаружения; это фрагмент, а не обещание боевого SAPI.

Эта маска не заменяет журнал задания: сохраняйте собственные статусы «принято», «обработано», «повторить». CONNECTION_TIMEOUT относится к состоянию PHP-соединения, а не к HTTP-тайм-ауту внешнего API.

Полный договор вызова

Часть вызоваПолный договор
ПараметрыНет.
ВозвратБитовая маска из CONNECTION_NORMAL (0), CONNECTION_ABORTED и CONNECTION_TIMEOUT.
ПроверкаДля ненулевых флагов используйте ($status & FLAG) !== 0; равенство подходит лишь когда точно исключены комбинации.

Ошибки и границы. Ноль означает нормальное состояние, поэтому условие if ($status) не различает конкретные ненормальные причины.

Версии и платформа. Доступные биты заданы константами текущего PHP; наблюдение разрыва зависит от SAPI.

Рядом: connection_aborted, ignore_user_abort.

Карта полного раздела Miscellaneous.

exitНемедленно прекратить текущий PHP-сценарий с сообщением или кодом CLI.

PHP 4+; proper function semantics — PHP 8.4+ · standard

exit(string|int $status = 0): never

Немедленно прекратить текущий PHP-сценарий с сообщением или кодом CLI.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Точка без возврата
  1. Проверить условие остановки
  2. Сформировать сообщение либо целый код
  3. exit начинает завершение
  4. Shutdown/destructors; обычное продолжение отсутствует

Первый запуск и развитие задачи

Строковый status печатается, а код завершения остаётся нулевымСамостоятельный пример
<?php
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/child.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('child'); }
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$status = proc_close($process);
echo 'stdout=', $stdout, "\nstatus=", $status, "\nstderr=", $stderr;
Ожидаемый результат
stdout=maintenance
status=0
stderr=

Дочерний CLI завершился сам. Строка — сообщение в stdout; это не ненулевой код ошибки. Для CLI-автоматизации чаще пишут диагностику в STDERR и передают целый код.

Целый код, shutdown и граница finally в PHP 8.4+Самостоятельный пример
<?php
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/child.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('child'); }
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$status = proc_close($process);
echo $stdout, 'status=', $status, "\n", 'stderr=', $stderr;
Ожидаемый результат
before
shutdown
status=4
stderr=

exit(status: 4) — именованный аргумент, доступный с PHP 8.4. Shutdown-функция выполняется, строка finally отсутствует: exit не проходит через этот блок.

В библиотечном методе часто удобнее выбросить исключение и позволить верхней границе сформировать HTTP/CLI-ответ. После header("Location: ...") сценарий сам не прекращается; если продолжение опасно, завершите его явно на границе контроллера.

Полный договор вызова

Часть вызоваПолный договор
status: stringПечатается перед остановкой; код процесса — 0.
status: intКод процесса. Используйте 0…254; 255 зарезервирован PHP.
Возврат neverУспешный вызов не возвращается к следующей строке.
ЗавершениеShutdown-функции и деструкторы запускаются, но finally не выполняется. Нельзя отключить или затенить namespaced-функцией.

Ошибки и границы. С PHP 8.4 применяются обычные правила типов и strict_types; массив/ресурс вызывают TypeError. До 8.4 они приводились к строке. Параметрless exit в shutdown/destructor с 8.4 сбрасывает прежний код на 0.

Версии и платформа. С PHP 8.4 доступны именованный аргумент и variable function. Синтаксис exit; без скобок сохраняется как специальная форма.

Рядом: die.

Карта полного раздела Miscellaneous.

dieИспользовать точный псевдоним exit; отдельной семантики у die нет.

PHP 4+; alias of exit, proper function semantics — PHP 8.4+ · standard

die(string|int $status = 0): never

Использовать точный псевдоним exit; отдельной семантики у die нет.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Псевдоним без новой возможности
  1. Код встречает die
  2. Читает его как exit
  3. Применяет тот же договор status
  4. Завершает сценарий

Первый запуск и развитие задачи

die — тот же вызов, в PHP 8.4+ доступный по строковому имениСамостоятельный пример
<?php
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/child.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('child'); }
$out = stream_get_contents($pipes[1]); fclose($pipes[1]);
$err = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $out, "|", $code, "|", $err;
Ожидаемый результат
denied|0|

Переменная $stop содержит имя alias. Строковый status печатается, поэтому код процесса остаётся 0.

Целый аргумент die становится кодом процессаСамостоятельный пример
<?php
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/child.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('child'); }
$out = stream_get_contents($pipes[1]); fclose($pipes[1]);
$err = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo 'empty=', $out === '' ? 'yes' : 'no', "\ncode=", $code, "\n";
Ожидаемый результат
empty=yes
code=3

die(3) ничего не печатает и завершает только дочерний процесс с кодом 3. Родитель может принять решение по коду.

Не выбирайте между die и exit по выдуманной производительности. В проекте полезнее один согласованный стиль и явная политика: где завершает CLI, а где библиотека возвращает/выбрасывает ошибку.

Полный договор вызова

Часть вызоваПолный договор
СтатусТе же string/int и правила кода 0…254, что у exit.
Возвратnever: выполнение не продолжается.
AliasСигнатура, типы, shutdown/destructor/finally и изменения PHP 8.4 полностью принадлежат exit.

Ошибки и границы. Все ошибки типов и ограничения exit применяются без изменений.

Версии и платформа. Официальная страница — alias-ссылка на exit; самостоятельный контракт не расходится с ней.

Рядом: exit.

Карта полного раздела Miscellaneous.

evalВыполнить строку как PHP-код — опасная граница и почти всегда сигнал выбрать более ясную модель.

PHP 4+ · standard

eval(string $code): mixed

Выполнить строку как PHP-код — опасная граница и почти всегда сигнал выбрать более ясную модель.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Текст становится исполняемым кодом
  1. Строка входит в eval
  2. Компилятор PHP разбирает её в текущей области
  3. Код получает права процесса
  4. return/изменённые переменные выходят наружу

Первый запуск и развитие задачи

Фиксированный автором фрагмент видит локальную переменную и возвращает значениеСамостоятельный пример
<?php
function totalWithInternalRule(int $price): int
{
    $result = eval('return $price * 2;');
    if (!is_int($result)) { throw new RuntimeException('rule'); }
    return $result;
}
echo totalWithInternalRule(75), "\n";
Ожидаемый результат
150

Строка кода записана разработчиком и не приходит от пользователя. return завершает только eval и отдаёт 150 в $result. Пример показывает механику, а не рекомендацию строить правила строками.

Поймать ParseError и выбрать функцию без evalСамостоятельный пример
<?php
try {
    eval('return 1 + ;');
} catch (ParseError $error) {
    echo "invalid internal code\n";
}
$rules = [
    'double' => static fn (int $value): int => $value * 2,
    'vat20' => static fn (int $value): int => intdiv($value * 120, 100),
];
echo $rules['vat20'](500), "\n";
Ожидаемый результат
invalid internal code
600

ParseError перехватывается с PHP 7. Таблица известных callable решает обычную задачу выбора правила без исполнения произвольного текста и допускает статический анализ.

Реальная потребностьБолее ясная альтернатива
Выбрать одно из известных правилМассив callable / match / Strategy.
Шаблон страницыПодключаемый доверенный шаблон или шаблонизатор с ограниченным языком.
Формула пользователяПарсер формул с белым списком операций и лимитами, не PHP-код.
КонфигурацияJSON/YAML/массив со схемой и проверкой типов.

Нельзя «надёжно очистить» произвольный PHP-текст регулярным выражением. Изоляция требует отдельного процесса/контейнера, минимальных прав, лимитов и всё равно не превращает eval в безопасный пользовательский язык.

eval() выполняет PHP-текст внутри текущего PHP-процесса; он не запускает Python, Node.js или C-программу. Для этой задачи используйте отдельный справочник запуска программ и цельный пример обмена JSON с Python/Node.js.

Полный договор вызова

Часть вызоваПолный договор
codePHP-код без начального/конечного тега; инструкции завершаются ;. Можно выйти в HTML-режим тегами, но это ещё сильнее усложняет границу.
ОбластьВидит и может менять переменные места вызова. Объявленные функции/классы создаются в глобальном namespace, как в отдельном include-файле.
Возвратnull, если внутри нет return; иначе значение return. ParseError при синтаксической ошибке с PHP 7.
СинтаксисЭто language construct: variable function и named arguments не применяются. Фатальная ошибка внутри завершает весь сценарий.

Ошибки и границы. Никогда не соединяйте eval с полем формы, URL, записью БД, загруженным файлом или ответом API. set_error_handler не ловит ParseError; используйте catch (ParseError).

Версии и платформа. С PHP 7 синтаксическая ошибка выбрасывает ParseError; раньше eval возвращал false. Поведение области и глобальных объявлений принципиально важно.

Карта полного раздела Miscellaneous.

ignore_user_abortРешить, должен ли PHP продолжать после обнаруженного отключения клиента.

PHP 4+ · standard

ignore_user_abort(?bool $enable = null): int

Решить, должен ли PHP продолжать после обнаруженного отключения клиента.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Политика disconnect
  1. Сохранить прежний режим
  2. Включить продолжение только для ограниченного участка
  3. Проверять собственный deadline/идемпотентность
  4. Восстановить прежний режим

Первый запуск и развитие задачи

Изменить режим и восстановить прежнее значениеСамостоятельный пример
<?php
$before = ignore_user_abort();
$returned = ignore_user_abort(true);
echo $returned === $before ? "previous returned\n" : "mismatch\n";
echo ignore_user_abort() === 1 ? "enabled\n" : "disabled\n";
ignore_user_abort((bool) $before);
echo ignore_user_abort() === $before ? "restored\n" : "not restored\n";
Ожидаемый результат
previous returned
enabled
restored

Вызов с аргументом возвращает предыдущее состояние, а не новое. После опыта исходная настройка восстановлена.

Локальный HTTP-опыт: клиент закрывает сокетФрагмент или команда
<?php
// endpoint.php — только для отдельного localhost-теста.
ignore_user_abort(true);
while (ob_get_level() > 0) { ob_end_flush(); }
header('Content-Type: text/plain');
for ($part = 1; $part <= 200; $part++) {
    echo str_repeat('x', 65536);
    flush();
    if (connection_aborted()) {
        file_put_contents(__DIR__ . '/observed.txt',
            connection_status() . "\n", LOCK_EX);
        break;
    }
    usleep(10000);
}

Запускайте файл отдельным php -S на 127.0.0.1, подключайте локальный сокет, прочитайте начало ответа и закройте клиент. Проверенная harness-процедура хранится в evidence/misc-connection-http-test.py. Буферы, веб-сервер и прокси влияют на момент обнаружения; это фрагмент, а не обещание боевого SAPI.

Продолжение после разрыва не подтверждает доставку ответа и не защищает от kill, timeout, сбоя хоста или исключения. Для заказа сначала фиксируйте транзакционное состояние, а тяжёлую работу отдавайте очереди.

Полный договор вызова

Часть вызоваПолный договор
enable=true/falseИзменяет одноимённую INI-настройку для текущего выполнения.
enable=null/нет аргументаТолько читает прежнее/текущее состояние. Nullable с PHP 8.
ВозвратПредыдущее состояние как int 0/1.
CLIЕсли TTY исчезнет, запись может завершить сценарий, если игнорирование выключено.

Ошибки и границы. PHP замечает разрыв при попытке отправки, а буферы могут отложить этот момент. Не используйте настройку для бесконечного фонового цикла.

Версии и платформа. Параметр nullable с PHP 8. Поведение зависит от SAPI и буферизации.

Рядом: connection_aborted, connection_status.

Карта полного раздела Miscellaneous.

sys_getloadavgПолучить среднюю системную нагрузку за 1, 5 и 15 минут там, где ОС это поддерживает.

PHP 5.1.3+; unavailable on Windows · standard

sys_getloadavg(): array|false

Получить среднюю системную нагрузку за 1, 5 и 15 минут там, где ОС это поддерживает.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Метрика → решение приложения
  1. Проверить доступность
  2. Получить ровно три окна
  3. Сопоставить с CPU/воркерами и собственной политикой
  4. Отложить необязательное задание либо продолжить

Первый запуск и развитие задачи

Проверить наличие функции до платформенного вызоваСамостоятельный пример
<?php
if (!function_exists('sys_getloadavg')) {
    echo "not available on this Windows runtime\n";
} else {
    $load = sys_getloadavg();
    echo is_array($load) && count($load) === 3 ? "three samples\n" : "unavailable\n";
}
Ожидаемый результат
not available on this Windows runtime

PHP 8.5.11 для Windows не определяет функцию. function_exists проверяет реальную сборку; это честный платформенный результат, а не имитация Unix.

На Unix прочитать три окна и применить собственный порогПример для указанного окружения
<?php
if (!function_exists('sys_getloadavg')) {
    throw new RuntimeException('Нужна Unix-платформа с sys_getloadavg');
}
$load = sys_getloadavg();
if (!is_array($load) || count($load) !== 3) {
    throw new RuntimeException('Метрика недоступна');
}
[$one, $five, $fifteen] = $load;
printf("1m=%.2f 5m=%.2f 15m=%.2f\n", $one, $five, $fifteen);
$workers = 4;
echo $one > $workers * 2 ? "defer optional job\n" : "capacity policy allows check\n";

Вывод зависит от Unix-хоста, поэтому это проверенный синтаксически контекстный пример. Load average — длина runnable/uninterruptible очереди по правилам ОС, не процент CPU. Порог 2×workers — лишь явная политика примера.

Для production-наблюдения собирайте также CPU, память, latency, очередь и ошибки. Один load average не диагностирует причину и не должен автоматически выключать обязательную обработку.

Полный договор вызова

Часть вызоваПолный договор
ПараметрыНет.
ВозвратТри sample в порядке 1/5/15 минут; false при отказе.
WindowsФункция не реализована. Проверяйте function_exists или используйте платформенный мониторинг.
СмыслНе процент загрузки и не число запросов PHP. Интерпретация зависит от ОС и количества CPU/воркеров.

Ошибки и границы. false и отсутствие функции — разные состояния. Не индексируйте результат до проверки.

Версии и платформа. Изолированная Windows-проверка зафиксировала отсутствие в PHP 8.5.11; Unix-значения намеренно не подделываются.

Рядом: hrtime.

Карта полного раздела Miscellaneous.

time_sleep_untilЗаблокировать текущий процесс до абсолютной Unix-отметки времени.

PHP 5.1+ · standard

time_sleep_until(float $timestamp): bool

Заблокировать текущий процесс до абсолютной Unix-отметки времени.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Абсолютный срок
  1. Рассчитать wakeAt по проверенным данным
  2. Убедиться, что срок в будущем и ожидание короткое
  3. time_sleep_until блокирует процесс
  4. После true перепроверить деловое условие

Первый запуск и развитие задачи

Подождать до близкой абсолютной отметкиСамостоятельный пример
<?php
$wakeAt = microtime(true) + 0.02;
$ok = time_sleep_until($wakeAt);
var_dump($ok);
var_dump(microtime(true) >= $wakeAt);
Ожидаемый результат
bool(true)
bool(true)

Пауза около 20 мс ограничена учебным запуском. microtime(true) даёт дробную Unix-отметку; повторное значение после возврата не меньше цели.

Прошлая отметка: предупреждение и falseСамостоятельный пример
<?php
$warnings = 0;
set_error_handler(static function (int $level) use (&$warnings): bool {
    if ($level === E_WARNING) { $warnings++; return true; }
    return false;
});
try {
    $ok = time_sleep_until(microtime(true) - 1);
} finally {
    restore_error_handler();
}
var_dump($ok);
echo 'warnings=', $warnings, "\n";
Ожидаемый результат
bool(false)
warnings=1

Предупреждение обработано только ради наблюдаемого опыта; рабочий код проверяет, что deadline ещё в будущем, и не подавляет другие ошибки.

Для задания на завтра используйте планировщик/очередь с available_at: sleeping-процесс удерживает воркер и может потеряться при перезапуске. Изменение системных wall-clock часов влияет на абсолютные сроки; для timeout участка выбирайте hrtime.

Полный договор вызова

Часть вызоваПолный договор
timestampUnix timestamp с дробной частью; для точного относительного интервала сначала сформулируйте, нужны ли wall-clock или monotonic часы.
Возвратtrue при достижении срока, false при отказе.
Прошлая отметкаE_WARNING и false.
СигналыОфициальная заметка: доставляются после пробуждения.

Ошибки и границы. Не держите открытые транзакции и пользовательские сессии во время ожидания. Предупреждение прошлой даты нужно предотвращать, а не скрывать @.

Версии и платформа. Функция принимает float; time() округляет до целой секунды и может создавать впечатление «проснулся на секунду раньше», если сравнивать разные единицы.

Рядом: sleep, usleep, time_nanosleep, hrtime.

Карта полного раздела Miscellaneous.

__halt_compilerОстановить компиляцию текущего файла и оставить после конструкции необрабатываемые байты данных.

PHP 5.1+ · standard

__halt_compiler(): void

Остановить компиляцию текущего файла и оставить после конструкции необрабатываемые байты данных.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Один файл = загрузчик + данные
  1. PHP компилирует загрузчик
  2. __halt_compiler фиксирует offset
  3. Оставшиеся bytes не компилируются
  4. Загрузчик читает хвост из __FILE__ по offset

Первый запуск и развитие задачи

Прочитать текст, приложенный к собственному файлуСамостоятельный пример
<?php
$source = file_get_contents(__FILE__);
$payload = substr($source, __COMPILER_HALT_OFFSET__);
echo trim($payload), "\n";
__halt_compiler();
MANUAL-PAYLOAD
Ожидаемый результат
MANUAL-PAYLOAD

__COMPILER_HALT_OFFSET__ — byte-позиция первого байта после конструкции. Компилятор не разбирает MANUAL-PAYLOAD как PHP; код до конструкции читает этот хвост как данные.

Проверить встроенный JSON-манифест перед использованиемСамостоятельный пример
<?php
$handle = fopen(__FILE__, 'rb');
if ($handle === false || fseek($handle, __COMPILER_HALT_OFFSET__) !== 0) {
    throw new RuntimeException('payload');
}
$json = ltrim((string) stream_get_contents($handle));
fclose($handle);
$manifest = json_decode($json, true, flags: JSON_THROW_ON_ERROR);
echo $manifest['package'], ':', $manifest['files'], "\n";
__halt_compiler();
{"package":"demo","files":3}
Ожидаемый результат
demo:3

JSON остаётся обычными данными и проходит json_decode. В реальном single-file package дополнительно проверяют подпись/хеш, размер и схему; сам offset не доказывает целостность.

Практическое применение — PHAR/single-file installer. Для обычного приложения отдельный ресурсный файл обычно проще обновлять, подписывать и проверять. Не используйте конструкцию как замену системе контроля версий для «выключенного» кода.

Полный договор вызова

Часть вызоваПолный договор
Параметры/возвратНет параметров; void. Компиляция кода после конструкции прекращается.
__COMPILER_HALT_OFFSET__Константа появляется только в файле с этой конструкцией и содержит byte-offset начала хвоста.
ОбластьРазрешена только на самом внешнем уровне файла; нельзя вызвать из функции/метода.
ГраницаЭто compiler construct, не обычная Reflection-функция. Код после неё не проверяется как PHP.

Ошибки и границы. Неверное расположение даёт compile error. Любой парсер хвоста обязан ограничивать размер и проверять формат; приложенные bytes не становятся доверенными автоматически.

Версии и платформа. Offset измеряется в bytes текущего файла. Перенос строк/кодировка перед конструкцией изменяют число.

Рядом: php_strip_whitespace.

Карта полного раздела Miscellaneous.

packСобрать бинарную строку по точной схеме протокола или формата файла.

PHP 4+; endian float/double codes — PHP 7.0.15/7.1.1+ · standard

pack(string $format, mixed ...$values): string

Собрать бинарную строку по точной схеме протокола или формата файла.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Поля → bytes
  1. Прочитать спецификацию формата
  2. Выбрать размер и endian для каждого поля
  3. pack потребляет values по format
  4. Проверить длину/hex и отправить либо сохранить bytes

Первый запуск и развитие задачи

Собрать переносимый бинарный заголовок с явным byte orderСамостоятельный пример
<?php
$binary = pack('NnC', 0x10203040, 0x5060, 0x70);
echo bin2hex($binary), "\n";
echo strlen($binary), " bytes\n";
Ожидаемый результат
10203040506070
7 bytes

N всегда пишет 32-bit big-endian, n — 16-bit big-endian, C — один byte. Поэтому результат не зависит от native endian этой машины.

Записать подпись фиксированной длины и ширину изображенияСамостоятельный пример
<?php
$record = pack('Z8N', 'IMG', 640);
echo bin2hex($record), "\n";
echo strlen($record), "\n";
Ожидаемый результат
494d47000000000000000280
12

Z8 занимает восемь bytes: IMG, NUL-терминатор и дополнение. N добавляет четыре bytes 00000280. Это бинарная запись, а не UTF-8-текстовый CSV.

КодЧто именно записывает/читает
a / A / ZСтрока с NUL-дополнением / SPACE-дополнением / NUL-terminated; A при unpack убирает конечные ASCII whitespace и NUL, a сохраняет NUL, Z убирает NUL-хвост.
h / HШестнадцатеричные полубайты: младший nibble первым / старший nibble первым. Повтор задаёт число символов из одного аргумента.
c / CЗнаковый / беззнаковый byte.
s / S16-bit signed/unsigned в машинном byte order.
n / v16-bit unsigned: big-endian / little-endian.
i / ISigned/unsigned integer машинного размера и byte order.
l / L32-bit signed/unsigned в машинном byte order.
N / V32-bit unsigned: big-endian / little-endian.
q / Q64-bit signed/unsigned в машинном byte order; недоступны на 32-bit сборках.
J / P64-bit unsigned: big-endian / little-endian; недоступны на 32-bit сборках.
f / g / GFloat: машинное представление / little-endian / big-endian.
d / e / EDouble: машинное представление / little-endian / big-endian.
x / X / @Вставить NUL / отступить на byte назад / дополнить NUL до абсолютной позиции.

Для сетевого протокола выбирайте N/n/J или V/v/P по его спецификации. Коды i/I/l/L/S зависят от машины и плохо подходят для обмена между языками без явного договора. Бинарная строка может содержать NUL: не обрабатывайте её текстовыми функциями, ожидающими кодировку.

Полный договор вызова

Часть вызоваПолный договор
formatПоследовательность кодов и необязательных repeat. Для a/A/h/H repeat — число символов одного аргумента; для @ — абсолютная позиция; для остальных — число потребляемых значений. * повторяет до конца входных values.
valuesЗначения в порядке схемы. Количество, диапазоны и смысл обязан проверить код протокола.
ВозвратБинарная PHP-string. С PHP 8 pack больше не возвращает false при отказе.
Signed/unsignedПри pack различие кодов не меняет bytes; оно влияет на unpack. PHP int остаётся signed и машинного размера.

Ошибки и границы. Неверная схема, лишние/недостающие values, выход за диапазон и float→int могут дать предупреждение/ValueError либо неподходящие bytes. На 32-bit нет q/Q/J/P; большие unsigned значения могут потерять точность ещё до pack.

Версии и платформа. PHP 7.2 документировал endian float/double; с PHP 8 возврат только string. Никогда не полагайтесь на native order без требования формата.

Рядом: unpack.

Карта полного раздела Miscellaneous.

uniqidСоздать time-based строковую метку для низкой цены конфликта, но не секрет и не гарантию уникальности.

PHP 4+ · standard

uniqid(string $prefix = "", bool $more_entropy = false): string

Создать time-based строковую метку для низкой цены конфликта, но не секрет и не гарантию уникальности.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Выбрать требуемое свойство
  1. Нужна только временная подпись лога/превью → uniqid допустим
  2. Нужна уникальность БД → UNIQUE + обработка конфликта/UUID
  3. Нужна непредсказуемость → random_bytes/Randomizer Secure
  4. Не смешивать эти свойства

Первый запуск и развитие задачи

Получить временную читаемую метку и проверить только её формуСамостоятельный пример
<?php
$id = uniqid('job-');
var_dump(str_starts_with($id, 'job-'));
var_dump(strlen($id) === strlen('job-') + 13);
var_dump((bool) preg_match('/^job-[0-9a-f]+$/D', $id));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Конкретное время-зависимое значение намеренно не фиксируется. Проверка формы не превращает ID в гарантированно уникальный или секретный.

Сравнить метку uniqid с настоящим секретным токеномСамостоятельный пример
<?php
$label = uniqid('preview-', true);
$token = bin2hex(random_bytes(16));
var_dump(str_starts_with($label, 'preview-'));
var_dump(strlen($label) === strlen('preview-') + 23);
var_dump(strlen($token) === 32 && ctype_xdigit($token));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

more_entropy удлиняет time-based label, но Manual всё равно не гарантирует uniqueness/unguessability. Для reset-ссылки используется random_bytes; в БД также ставят UNIQUE и обрабатывают редкий конфликт.

Идентификатор заказа лучше выдаёт база/доменная схема; парольный reset, CSRF и API-key требуют CSPRNG. Изменение системных часов и параллельные узлы увеличивают риск совпадения. prefix из внешнего ввода не делает безопасное имя файла.

Полный договор вызова

Часть вызоваПолный договор
prefixДобавляется дословно. Может различать узлы, но не координирует их часы и не санитизирует путь/HTML/SQL.
more_entropy=falseПустой prefix → 13 characters. Основа — текущее время с microsecond precision.
more_entropy=trueПустой prefix → 23 characters; добавляется значение внутреннего генератора, повышая вероятность различия, но не создавая CSPRNG-токен.
ВозвратСтрока; Manual дважды предупреждает, что uniqueness не гарантирована.

Ошибки и границы. Не используйте uniqid для аутентификации, доступа, подписи, nonce или имен, где угадывание раскрывает файл. more_entropy не исправляет эту границу.

Версии и платформа. Под Cygwin more_entropy должен быть true. Длина относится к ASCII characters/bytes текущего формата, но не является обещанием будущнего бизнес-ID.

Карта полного раздела Miscellaneous.

unpackРазобрать бинарную строку по известной схеме в ассоциативный массив.

PHP 4+; offset — PHP 7.1+ · standard

unpack(string $format, string $string, int $offset = 0): array|false

Разобрать бинарную строку по известной схеме в ассоциативный массив.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Bytes → проверенные поля
  1. Проверить magic/version/length
  2. Выбрать explicit endian schema
  3. unpack читает от offset
  4. Проверить false, ключи и предметные диапазоны

Первый запуск и развитие задачи

Разобрать тот же переносимый сетевой заголовокСамостоятельный пример
<?php
$binary = hex2bin('10203040506070');
if ($binary === false) { throw new RuntimeException('hex'); }
$header = unpack('Nrequest/nflags/Cversion', $binary);
if ($header === false) { throw new RuntimeException('header'); }
echo $header['request'], "\n";
echo dechex($header['flags']), "\n";
echo dechex($header['version']), "\n";
Ожидаемый результат
270544960
5060
70

Имена request/flags/version становятся ключами массива. N/n/C читают 4/2/1 bytes с тем же endian-договором, что pack.

Пропустить префикс и прочитать два поля из нужного offsetСамостоятельный пример
<?php
$frame = "AA" . pack('n2', 300, 400);
$size = unpack('nwidth/nheight', $frame, 2);
if ($size === false) { throw new RuntimeException('frame'); }
echo $size['width'], 'x', $size['height'], "\n";
Ожидаемый результат
300x400

Offset 2 отсчитывается в bytes и пропускает ASCII-префикс AA. Имена обязательны для двух разных полей: иначе numeric key может быть перезаписан следующим кодом.

КодЧто именно записывает/читает
a / A / ZСтрока с NUL-дополнением / SPACE-дополнением / NUL-terminated; A при unpack убирает конечные ASCII whitespace и NUL, a сохраняет NUL, Z убирает NUL-хвост.
h / HШестнадцатеричные полубайты: младший nibble первым / старший nibble первым. Повтор задаёт число символов из одного аргумента.
c / CЗнаковый / беззнаковый byte.
s / S16-bit signed/unsigned в машинном byte order.
n / v16-bit unsigned: big-endian / little-endian.
i / ISigned/unsigned integer машинного размера и byte order.
l / L32-bit signed/unsigned в машинном byte order.
N / V32-bit unsigned: big-endian / little-endian.
q / Q64-bit signed/unsigned в машинном byte order; недоступны на 32-bit сборках.
J / P64-bit unsigned: big-endian / little-endian; недоступны на 32-bit сборках.
f / g / GFloat: машинное представление / little-endian / big-endian.
d / e / EDouble: машинное представление / little-endian / big-endian.
x / X / @Вставить NUL / отступить на byte назад / дополнить NUL до абсолютной позиции.

Безымянные поля получают numeric keys с 1, но нумерация начинается заново для каждого format-code: следующий код может перезаписать данные. Поэтому в рабочем протоколе именуйте каждое поле. Unpack не проверяет CRC, magic, допустимый enum или общую длину сообщения — это делает код формата.

Полный договор вызова

Часть вызоваПолный договор
formatКоды pack плюс имена полей; поля разделяются /. При repeat ключи получают числовые суффиксы. a/A/Z по-разному сохраняют/убирают конечные NUL/ASCII whitespace.
stringБинарные bytes. До разбора проверьте минимальную/точную длину и версию протокола.
offsetByte-offset начала разбора, доступен с PHP 7.1.
ВозвратАссоциативный массив или false. Большой unsigned может стать отрицательным из-за signed PHP int.

Ошибки и границы. Короткий/повреждённый буфер, неверный format и offset требуют явной обработки false/диагностики. Не распаковывайте произвольный огромный input без лимита размера.

Версии и платформа. Endian float/double коды доступны в современном PHP; native-order коды остаются платформенными.

Рядом: pack.

Карта полного раздела Miscellaneous.

get_browserСопоставить строку User-Agent с записью внешней базы browscap.ini.

PHP 4+ · standard

get_browser(?string $user_agent = null, bool $return_array = false): object|array|false

Сопоставить строку User-Agent с записью внешней базы browscap.ini.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

User-Agent → запись базы
  1. Получить строку заголовка или лога
  2. Загрузить настроенную версию browscap
  3. Найти лучшее правило
  4. Вернуть заявленные capabilities или false

Первый запуск и развитие задачи

Запустить get_browser с отдельным локальным browscap.iniСамостоятельный пример
<?php
$command = [PHP_BINARY, '-n', '-d', 'browscap=' . __DIR__ . '/browscap.ini',
    __DIR__ . '/worker.php'];
$process = proc_open($command,
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('worker'); }
$out = stream_get_contents($pipes[1]); fclose($pipes[1]);
$err = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $out, 'exit=', $code, "\n", 'stderr=', $err;
Ожидаемый результат
ManualBrowser|1.0|cookies=yes
exit=0
stderr=

Тестовый browscap передан только дочернему CLI на старте. База специально содержит один User-Agent и не претендует на актуальный каталог браузеров.

Без browscap функция выдаёт предупреждение и falseСамостоятельный пример
<?php
$command = [PHP_BINARY, '-n', __DIR__ . '/worker.php'];
$process = proc_open($command,
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('worker'); }
$out = stream_get_contents($pipes[1]); fclose($pipes[1]);
$err = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $out, 'exit=', $code, "\n", 'stderr=', $err;
Ожидаемый результат
warning
bool(false)
exit=0
stderr=

Дочерний PHP запущен с -n, поэтому browscap не настроен. Пользовательский error handler превращает ожидаемое предупреждение в наблюдаемый текст только для опыта.

Не принимайте решение о доступе, цене или безопасности по User-Agent. Поле cookies означает возможность браузера по базе, а не фактическое согласие/включение пользователя; это проверяется реальной cookie. Для интерфейса надёжнее feature detection и progressive enhancement.

Полный договор вызова

Часть вызоваПолный договор
user_agentЯвная строка либо null: тогда используется HTTP User-Agent текущего запроса. Это заявка клиента, а не доказанная модель устройства.
return_array=falseОбъект свойств; true — массив. Конкретные ключи зависят от browscap-базы.
Возврат falseИнформация не получена, в частности browscap не настроен.
Конфигурацияbrowscap — INI_SYSTEM-путь к внешнему файлу; база не поставляется с PHP и требует обновлений.

Ошибки и границы. Устаревшая/неверная база даёт Default Browser или ошибочную классификацию. Нельзя принимать произвольный путь к browscap во время запроса: setting читается на системном уровне.

Версии и платформа. Работа зависит от конкретного INI выбранного SAPI. Composer-пакет не автоматически настраивает встроенную функцию.

Карта полного раздела Miscellaneous.

highlight_fileПолучить HTML-подсветку PHP-исходника из файла для закрытой документации.

PHP 4+; generated HTML changed in PHP 8.3 · standard

highlight_file(string $filename, bool $return = false): string|bool

Получить HTML-подсветку PHP-исходника из файла для закрытой документации.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Файл → HTML-копия исходника
  1. Сервер читает весь разрешённый файл
  2. Lexer разбивает PHP-токены
  3. Генерируется HTML с inline-цветами
  4. Закрытая страница выводит/возвращает результат

Первый запуск и развитие задачи

Подсветить собственный учебный файл и проверить, что он не исполнилсяСамостоятельный пример
<?php
$html = highlight_file(__DIR__ . '/sample.php', true);
if (!is_string($html)) { throw new RuntimeException('highlight'); }
$plain = html_entity_decode(strip_tags($html), ENT_QUOTES | ENT_HTML5, 'UTF-8');
var_dump(str_contains($plain, '$message'));
var_dump(str_contains($plain, 'DEMO-NOT-A-SECRET'));
Ожидаемый результат
bool(true)
bool(true)

Функция читает и форматирует исходник, но не выполняет echo из sample.php. Текст-заглушка специально показывает главный риск: любые реальные секреты в исходнике тоже будут раскрыты.

Отсутствующий файл: диагностики и falseСамостоятельный пример
<?php
$warnings = 0;
set_error_handler(static function (int $level) use (&$warnings): bool {
    if ($level === E_WARNING) { $warnings++; return true; }
    return false;
});
try { $result = highlight_file(__DIR__ . '/absent.php', true); }
finally { restore_error_handler(); }
var_dump($result);
echo 'warnings=', $warnings, "\n";
Ожидаемый результат
bool(false)
warnings=2

PHP 8.5.11 выдаёт отдельные предупреждения открытия файла и highlight_file. Код проверяет false, а не связывает бизнес-логику с числом диагностик. Путь фиксирован автором; разрешённые документы перечисляют явно и не показывают пользователю системные пути.

Не превращайте filename из query-параметра в публичный просмотрщик: пользователь сможет запросить конфигурацию, ключи и исходники. Для документации лучше хранить отдельную проверенную копию примера или репозиторный snippet без секретов.

Полный договор вызова

Часть вызоваПолный договор
filenameПуть к читаемому PHP-файлу. Функция раскрывает его исходный текст.
return=falseHTML сразу печатается; возврат true/false.
return=trueHTML возвращается строкой; при отказе false. Внутри используется output buffering, поэтому нельзя вызывать в ob_start callback.
ОформлениеЦвета берутся из highlight.string/comment/keyword/default/html. Генерируемая разметка изменилась в PHP 8.3 и может меняться снова.

Ошибки и границы. Отсутствие/права дают warning и false. open_basedir и реальные права файла применяются, но не заменяют allowlist.

Версии и платформа. Не привязывайте CSS/тест к точной внутренней разметке. return=true несовместим с ob_start callback.

Рядом: highlight_string, show_source, php_strip_whitespace.

Карта полного раздела Miscellaneous.

highlight_stringСформировать HTML-подсветку доверенной строки PHP-кода без её выполнения.

PHP 4+; HTML changed 8.3; return type refined 8.4 · standard

highlight_string(string $string, bool $return = false): string|true

Сформировать HTML-подсветку доверенной строки PHP-кода без её выполнения.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Текст → подсвеченный документ
  1. Получить доверенный пример
  2. Lexer разбирает токены без выполнения
  3. Генерируется HTML
  4. Вернуть строку либо вывести

Первый запуск и развитие задачи

Подсветить доверенную строку и получить HTMLСамостоятельный пример
<?php
$source = '<?php $total = 2 + 3; echo $total;';
$html = highlight_string($source, true);
$plain = html_entity_decode(strip_tags($html), ENT_QUOTES | ENT_HTML5, 'UTF-8');
var_dump(is_string($html));
var_dump(str_contains($plain, '$total'));
var_dump(str_contains($plain, '2 + 3'));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Исходная строка включает открывающий PHP-тег, как требует Manual. Подсветка не запускает вычисление 2+3.

Режим вывода возвращает true и всё равно не исполняет кодСамостоятельный пример
<?php
$ran = false;
ob_start();
$ok = highlight_string('<?php $ran = true;', false);
$html = ob_get_clean();
var_dump($ok);
var_dump(is_string($html) && $html !== '');
var_dump($ran);
Ожидаемый результат
bool(true)
bool(true)
bool(false)

Output buffer использован вокруг обычного вызова, а не как callback. Переменная ran остаётся false: PHP-текст только подсвечен.

Функция не делает недоверенный текст безопасным бизнес-кодом: она лишь показывает его. Если результат вставляется в большую HTML-страницу, учитывайте, что это уже сгенерированная HTML-разметка, а исходный пример храните отдельно.

Полный договор вызова

Часть вызоваПолный договор
stringPHP-код, включая открывающий тег
return=falseHTML печатается, возвращается true.
return=trueHTML возвращается string.
РазметкаЗависит от highlight.* и версии; изменилась в 8.3. Возврат уточнён с string|bool до string|true в 8.4.

Ошибки и границы. Не вызывайте return=true внутри callback ob_start: функция сама использует внутреннюю буферизацию.

Версии и платформа. Тестируйте наличие смысла/токенов, а не точные span/style, если обновляете PHP.

Рядом: highlight_file, show_source.

Карта полного раздела Miscellaneous.

php_strip_whitespaceУдалить комментарии и лишние пробелы из PHP-файла, сохранив токены кода.

PHP 5+ · standard

php_strip_whitespace(string $filename): string

Удалить комментарии и лишние пробелы из PHP-файла, сохранив токены кода.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Исходник → компактная копия
  1. Прочитать доверенный файл
  2. Tokenizer сохраняет нужные разделители токенов
  3. Убрать комментарии/лишний whitespace
  4. Проверить непустой результат и поведение

Первый запуск и развитие задачи

Создать компактную копию собственного fixture и проверить её результатСамостоятельный пример
<?php
$stripped = php_strip_whitespace(__DIR__ . '/source.php');
var_dump($stripped !== '');
var_dump(!str_contains($stripped, 'teaching comment'));
file_put_contents(__DIR__ . '/stripped.php', $stripped);
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/stripped.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__);
if (!is_resource($process)) { throw new RuntimeException('worker'); }
$out = stream_get_contents($pipes[1]); fclose($pipes[1]);
$err = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $out, 'exit=', $code, "\n", 'stderr=', $err;
Ожидаемый результат
bool(true)
bool(true)
compact
exit=0
stderr=

Исполняется только авторский локальный fixture. Комментарий исчез, поведение осталось. Это демонстрация, не production-minifier и не защита исходника.

Отсутствующий источник возвращает пустую строкуСамостоятельный пример
<?php
$warnings = 0;
set_error_handler(static function (int $level) use (&$warnings): bool {
    if ($level === E_WARNING) { $warnings++; return true; }
    return false;
});
try { $code = php_strip_whitespace(__DIR__ . '/absent.php'); }
finally { restore_error_handler(); }
var_dump($code === '');
echo 'warnings=', $warnings, "\n";
Ожидаемый результат
bool(true)
warnings=1

Пустая строка — официальный сигнал failure, поэтому её нельзя принимать за полезный компактный файл.

Не используйте функцию как обфускатор или безопасный публичный просмотр: строки, имена и секреты остаются. Комментарии могут содержать лицензии/документацию; удалять их из распространяемого файла можно только по принятой политике.

Полный договор вызова

Часть вызоваПолный договор
filenameПуть к читаемому PHP-исходнику.
ВозвратКомпактный исходник; пустая строка при failure.
INIРазбор учитывает short_open_tag текущего окружения.
CLI-аналогphp -w file.php.

Ошибки и границы. Пустой результат означает отказ чтения/разбора. Запись результата проверяется отдельно; не перезаписывайте единственную копию исходника.

Версии и платформа. Результат зависит от short_open_tag и синтаксиса версии PHP.

Рядом: highlight_file, __halt_compiler.

Карта полного раздела Miscellaneous.

show_sourceИспользовать псевдоним highlight_file; отдельной возможности у show_source нет.

PHP 4+ · standard

show_source(string $filename, bool $return = false): string|bool

Использовать псевдоним highlight_file; отдельной возможности у show_source нет.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Псевдоним → та же операция
  1. show_source получает path/return
  2. Выполняется highlight_file
  3. Получается та же HTML-разметка
  4. Применяется та же security allowlist

Первый запуск и развитие задачи

Проверить, что show_source — точный alias highlight_fileСамостоятельный пример
<?php
$alias = show_source(__DIR__ . '/sample.php', true);
$target = highlight_file(__DIR__ . '/sample.php', true);
var_dump(is_string($alias));
var_dump($alias === $target);
Ожидаемый результат
bool(true)
bool(true)

Оба имени возвращают одну и ту же разметку. Новый код обычно выбирает более понятное имя highlight_file.

Alias в режиме немедленного выводаСамостоятельный пример
<?php
ob_start();
$ok = show_source(__DIR__ . '/sample.php', false);
$html = ob_get_clean();
var_dump($ok);
var_dump(is_string($html) && $html !== '');
Ожидаемый результат
bool(true)
bool(true)

show_source печатает подсветку и возвращает true. Те же риски раскрытия пути/секретов относятся к нему без изменений.

Не создавайте два разных внутренних стандарта документации для alias и target. В интерфейсе показывайте один канонический термин, а alias сохраняйте для чтения старого кода.

Полный договор вызова

Часть вызоваПолный договор
AliasВсе параметры, возвраты, warnings, INI-цвета, буферизация и риски принадлежат highlight_file.
filenameПуть к раскрываемому исходнику.
returnfalse печатает и возвращает bool; true возвращает string либо false.

Ошибки и границы. Полностью совпадают с highlight_file, включая warning/false и запрет return=true внутри ob_start callback.

Версии и платформа. Официальная страница определяет show_source только как alias highlight_file.

Рядом: highlight_file, highlight_string.

Карта полного раздела Miscellaneous.

sapi_windows_cp_convПреобразовать bytes одной Windows-codepage в другую.

Windows SAPI, PHP 7.1+ · standard

sapi_windows_cp_conv(int|string $in_codepage, int|string $out_codepage, string $subject): ?string

Преобразовать bytes одной Windows-codepage в другую.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Bytes между двумя договорами
  1. Знать фактическую входную codepage
  2. Декодировать bytes в Unicode
  3. Закодировать в out_codepage
  4. Проверить string, сохранить метаданные кодировки

Первый запуск и развитие задачи

Преобразовать русскую строку UTF-8 → Windows-1251 → UTF-8Самостоятельный пример
<?php
$legacy = sapi_windows_cp_conv(65001, 1251, 'Привет');
if (!is_string($legacy)) { throw new RuntimeException('to 1251'); }
$restored = sapi_windows_cp_conv(1251, 65001, $legacy);
var_dump(bin2hex($legacy) === 'cff0e8e2e5f2');
var_dump($restored === 'Привет');
Ожидаемый результат
bool(true)
bool(true)

Кодовые страницы заданы явно: 65001 — UTF-8, 1251 — Cyrillic Windows. Это преобразование текста, а не исправление неизвестной кодировки угадыванием.

Повреждённый UTF-8: warning и nullСамостоятельный пример
<?php
$warnings = 0;
set_error_handler(static function (int $level) use (&$warnings): bool {
    if ($level === E_WARNING) { $warnings++; return true; }
    return false;
});
try { $converted = sapi_windows_cp_conv(65001, 1251, "\xFF"); }
finally { restore_error_handler(); }
var_dump($converted);
echo 'warnings=', $warnings, "\n";
Ожидаемый результат
NULL
warnings=1

0xFF не является самостоятельным UTF-8-символом. null нельзя превращать в пустой текст: это ошибка входных bytes.

Для переносимого приложения часто удобнее iconv/mbstring с явными именами кодировок. Не применяйте преобразование повторно к уже UTF-8 данным и не «лечите» mojibake случайным перебором codepage.

Полный договор вызова

Часть вызоваПолный договор
in_codepageЧисловой ID или имя фактической кодировки входных bytes.
out_codepageID/имя требуемой выходной кодировки.
subjectБинарная PHP-string, которую нужно интерпретировать именно как in_codepage.
ВозвратПреобразованная строка либо null. Неверная codepage/последовательность выдаёт E_WARNING.

Ошибки и границы. E_WARNING + null нужно обрабатывать вместе. Успешное преобразование не проверяет предметно допустимые символы.

Версии и платформа. Изолированно выполнено на Windows PHP 8.5.11; функции нет на Unix.

Рядом: sapi_windows_cp_get, sapi_windows_cp_is_utf8.

Карта полного раздела Miscellaneous.

sapi_windows_cp_getПрочитать текущую process, системную ANSI или OEM codepage Windows.

Windows SAPI, PHP 7.1+ · standard

sapi_windows_cp_get(string $kind = ""): int

Прочитать текущую process, системную ANSI или OEM codepage Windows.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Какую codepage вы измеряете
  1. Выбрать process/ansi/oem
  2. Вызвать функцию
  3. Получить ID
  4. Передать ID преобразованию либо диагностике

Первый запуск и развитие задачи

Различить process, ANSI и OEM codepageСамостоятельный пример
<?php
$process = sapi_windows_cp_get();
$ansi = sapi_windows_cp_get('ansi');
$oem = sapi_windows_cp_get('oem');
$fallback = sapi_windows_cp_get('anything-else');
var_dump($process > 0 && $ansi > 0 && $oem > 0);
var_dump($fallback === $process);
var_dump(sapi_windows_cp_is_utf8() === ($process === 65001));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Конкретные ANSI/OEM числа зависят от Windows-настроек, поэтому проверяется договор. Любой kind кроме ansi/oem относится к текущей process codepage.

Временно включить UTF-8 и вернуть исходную process codepageСамостоятельный пример
<?php
$before = sapi_windows_cp_get();
try {
    var_dump(sapi_windows_cp_set(65001));
    var_dump(sapi_windows_cp_get() === 65001);
    var_dump(sapi_windows_cp_is_utf8());
} finally {
    sapi_windows_cp_set($before);
}
var_dump(sapi_windows_cp_get() === $before);
Ожидаемый результат
bool(true)
bool(true)
bool(true)
bool(true)

Изменение действует только в отдельном учебном PHP-процессе. finally возвращает прежнее значение даже при исключении.

ANSI, OEM и process могут различаться. Значение не описывает кодировку произвольного файла/HTTP-тела: её задаёт источник данных.

Полный договор вызова

Часть вызоваПолный договор
kind="ansi"Системная ANSI codepage.
kind="oem"Системная OEM codepage.
Другой/пустой kindТекущая codepage PHP-процесса.
ВозвратЧисловой identifier codepage.

Ошибки и границы. Не подставляйте полученное process-значение вместо документированной кодировки протокола.

Версии и платформа. Изолированно выполнено на Windows; конкретные числа зависят от хоста.

Рядом: sapi_windows_cp_set, sapi_windows_cp_conv, sapi_windows_cp_is_utf8.

Карта полного раздела Miscellaneous.

sapi_windows_cp_is_utf8Проверить, совместима ли текущая process codepage с UTF-8.

Windows SAPI, PHP 7.1+ · standard

sapi_windows_cp_is_utf8(): bool

Проверить, совместима ли текущая process codepage с UTF-8.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Состояние процесса
  1. Прочитать текущую codepage
  2. Спросить UTF-8 compatibility
  3. Выбрать вывод/конверсию
  4. Не делать вывод о неизвестном входном файле

Первый запуск и развитие задачи

Различить process, ANSI и OEM codepageСамостоятельный пример
<?php
$process = sapi_windows_cp_get();
$ansi = sapi_windows_cp_get('ansi');
$oem = sapi_windows_cp_get('oem');
$fallback = sapi_windows_cp_get('anything-else');
var_dump($process > 0 && $ansi > 0 && $oem > 0);
var_dump($fallback === $process);
var_dump(sapi_windows_cp_is_utf8() === ($process === 65001));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Конкретные ANSI/OEM числа зависят от Windows-настроек, поэтому проверяется договор. Любой kind кроме ansi/oem относится к текущей process codepage.

Временно включить Windows-1251 и увидеть не-UTF-8 состояниеСамостоятельный пример
<?php
$before = sapi_windows_cp_get();
try {
    var_dump(sapi_windows_cp_set(1251));
    var_dump(sapi_windows_cp_get() === 1251);
    var_dump(sapi_windows_cp_is_utf8());
} finally {
    sapi_windows_cp_set($before);
}
var_dump(sapi_windows_cp_get() === $before);
Ожидаемый результат
bool(true)
bool(true)
bool(false)
bool(true)

1251 — корректная текстовая codepage, но она не UTF-8-compatible по договору функции. Код не меняет системную локаль Windows.

Проверка полезна для CLI-консоли, но HTTP/БД/файл имеют собственный договор кодировки. Один global-флаг процесса не заменяет проверку каждого boundary.

Полный договор вызова

Часть вызоваПолный договор
ПараметрыНет.
Возвратtrue для UTF-8-compatible process codepage, иначе false.
ОбластьТекущий PHP-процесс Windows; не содержимое конкретного файла.

Ошибки и границы. false не означает повреждённый текст; это характеристика current process codepage.

Версии и платформа. Изолированно выполнено на Windows; отсутствует на Unix.

Рядом: sapi_windows_cp_get, sapi_windows_cp_set, sapi_windows_cp_conv.

Карта полного раздела Miscellaneous.

sapi_windows_cp_setИзменить codepage текущего PHP-процесса Windows.

Windows SAPI, PHP 7.1+ · standard

sapi_windows_cp_set(int $codepage): bool

Изменить codepage текущего PHP-процесса Windows.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Временная настройка процесса
  1. Сохранить current codepage
  2. Установить нужный ID и проверить bool
  3. Выполнить ограниченный участок
  4. В finally вернуть прежний ID

Первый запуск и развитие задачи

Временно включить UTF-8 и вернуть исходную process codepageСамостоятельный пример
<?php
$before = sapi_windows_cp_get();
try {
    var_dump(sapi_windows_cp_set(65001));
    var_dump(sapi_windows_cp_get() === 65001);
    var_dump(sapi_windows_cp_is_utf8());
} finally {
    sapi_windows_cp_set($before);
}
var_dump(sapi_windows_cp_get() === $before);
Ожидаемый результат
bool(true)
bool(true)
bool(true)
bool(true)

Изменение действует только в отдельном учебном PHP-процессе. finally возвращает прежнее значение даже при исключении.

Временно включить Windows-1251 и увидеть не-UTF-8 состояниеСамостоятельный пример
<?php
$before = sapi_windows_cp_get();
try {
    var_dump(sapi_windows_cp_set(1251));
    var_dump(sapi_windows_cp_get() === 1251);
    var_dump(sapi_windows_cp_is_utf8());
} finally {
    sapi_windows_cp_set($before);
}
var_dump(sapi_windows_cp_get() === $before);
Ожидаемый результат
bool(true)
bool(true)
bool(false)
bool(true)

1251 — корректная текстовая codepage, но она не UTF-8-compatible по договору функции. Код не меняет системную локаль Windows.

Глобальное состояние усложняет библиотечный код: меняйте его на узкой границе CLI и всегда восстанавливайте. Для конкретной строки предпочтительнее явный cp_conv/iconv, не зависящий от текущего процесса.

Полный договор вызова

Часть вызоваПолный договор
codepageЧисловой identifier, например 65001 UTF-8 или 1251 Cyrillic Windows.
Возвратtrue при успехе, false при отказе.
ОбластьТекущий процесс; это не изменение системной локали, файла или уже созданной строки.

Ошибки и границы. Проверяйте false и восстанавливайте прежнее состояние. Параллельные/чужие компоненты могут ожидать другую codepage.

Версии и платформа. Изолированно выполнено в отдельном Windows PHP 8.5.11 процессе.

Рядом: sapi_windows_cp_get, sapi_windows_cp_is_utf8, sapi_windows_cp_conv.

Карта полного раздела Miscellaneous.

sapi_windows_generate_ctrl_eventОтправить CTRL+C/CTRL+BREAK процессу той же Windows console process group.

Windows SAPI, PHP 7.4+ · standard

sapi_windows_generate_ctrl_event(int $event, int $pid = 0): bool

Отправить CTRL+C/CTRL+BREAK процессу той же Windows console process group.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Управляемая остановка child
  1. Создать отдельную process group
  2. Child регистрирует handler и сообщает ready
  3. Parent отправляет CTRL_BREAK target group
  4. Child подтверждает событие и завершает cleanup

Первый запуск и развитие задачи

Отправить CTRL+BREAK отдельному child process groupСамостоятельный пример
<?php
@unlink(__DIR__ . '/ready.txt');
@unlink(__DIR__ . '/observed.txt');
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/worker.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__, null, ['create_process_group' => true]);
if (!is_resource($process)) { throw new RuntimeException('worker'); }
$deadline = microtime(true) + 2;
while (!is_file(__DIR__ . '/ready.txt') && microtime(true) < $deadline) { usleep(10000); }
$state = proc_get_status($process);
$sent = is_file(__DIR__ . '/ready.txt')
    && sapi_windows_generate_ctrl_event(PHP_WINDOWS_EVENT_CTRL_BREAK, $state['pid']);
$deadline = microtime(true) + 2;
while (!is_file(__DIR__ . '/observed.txt') && microtime(true) < $deadline) { usleep(10000); }
$observed = is_file(__DIR__ . '/observed.txt') ? trim(file_get_contents(__DIR__ . '/observed.txt')) : '';
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $sent ? "sent\n" : "not sent\n";
echo $observed === (string) PHP_WINDOWS_EVENT_CTRL_BREAK ? "break observed\n" : "not observed\n";
echo 'exit=', $code, " stdout=", $stdout, ' stderr=', $stderr;
Ожидаемый результат
sent
break observed
exit=0 stdout= stderr=

Child создан с новой process group и сам зарегистрировал handler. Событие направлено только его PID/group; текущий процесс не получает сигнал.

Несуществующей process group отправить событие нельзяСамостоятельный пример
<?php
$sent = sapi_windows_generate_ctrl_event(
    PHP_WINDOWS_EVENT_CTRL_BREAK, 2147483647
);
var_dump($sent);
Ожидаемый результат
bool(false)

Большой PID выбран как отсутствующая учебная process group. false обрабатывается как недоставленное управление, а не как подтверждение остановки.

Не используйте pid=0 без полного понимания группы: можно затронуть родителя/соседей. Для production supervisor после сигнала ждёт подтверждение, применяет deadline и только затем escalation.

Полный договор вызова

Часть вызоваПолный договор
eventPHP_WINDOWS_EVENT_CTRL_C или PHP_WINDOWS_EVENT_CTRL_BREAK.
pidID target process group; 0 означает все процессы текущей group.
Возвратtrue, если API принял отправку, false при отказе; это ещё не подтверждение реакции/завершения child.
ПредпосылкаПроцесс должен быть в совместимой console group; обычный произвольный PID не гарантирует доставку.

Ошибки и границы. true говорит об отправке события API, а не о том, что handler успешно сохранил данные. PID может переиспользоваться; связывайте его с созданным вами процессом.

Версии и платформа. Фактический test executed only against isolated child process group on Windows PHP 8.5.11.

Рядом: sapi_windows_set_ctrl_handler.

Карта полного раздела Miscellaneous.

sapi_windows_set_ctrl_handlerУстановить или удалить обработчик CTRL+C/CTRL+BREAK в Windows CLI.

Windows SAPI, PHP 7.4+ · standard

sapi_windows_set_ctrl_handler(?callable $handler, bool $add = true): bool

Установить или удалить обработчик CTRL+C/CTRL+BREAK в Windows CLI.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Событие → controlled shutdown
  1. Главный поток регистрирует handler
  2. Windows доставляет event
  3. Handler только отмечает отмену/начинает ограниченный cleanup
  4. Главный цикл завершает работу и удаляет handler

Первый запуск и развитие задачи

Добавить и удалить тот же handlerСамостоятельный пример
<?php
$handler = static function (int $event): void {
    echo 'event=', $event, "\n";
};
var_dump(sapi_windows_set_ctrl_handler($handler, true));
var_dump(sapi_windows_set_ctrl_handler($handler, false));
Ожидаемый результат
bool(true)
bool(true)

Событие не отправляется; опыт проверяет регистрацию и симметричное удаление того же callable в главном потоке.

Отправить CTRL+BREAK отдельному child process groupСамостоятельный пример
<?php
@unlink(__DIR__ . '/ready.txt');
@unlink(__DIR__ . '/observed.txt');
$process = proc_open([PHP_BINARY, '-n', __DIR__ . '/worker.php'],
    [0 => ['file', 'NUL', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
    $pipes, __DIR__, null, ['create_process_group' => true]);
if (!is_resource($process)) { throw new RuntimeException('worker'); }
$deadline = microtime(true) + 2;
while (!is_file(__DIR__ . '/ready.txt') && microtime(true) < $deadline) { usleep(10000); }
$state = proc_get_status($process);
$sent = is_file(__DIR__ . '/ready.txt')
    && sapi_windows_generate_ctrl_event(PHP_WINDOWS_EVENT_CTRL_BREAK, $state['pid']);
$deadline = microtime(true) + 2;
while (!is_file(__DIR__ . '/observed.txt') && microtime(true) < $deadline) { usleep(10000); }
$observed = is_file(__DIR__ . '/observed.txt') ? trim(file_get_contents(__DIR__ . '/observed.txt')) : '';
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($process);
echo $sent ? "sent\n" : "not sent\n";
echo $observed === (string) PHP_WINDOWS_EVENT_CTRL_BREAK ? "break observed\n" : "not observed\n";
echo 'exit=', $code, " stdout=", $stdout, ' stderr=', $stderr;
Ожидаемый результат
sent
break observed
exit=0 stdout= stderr=

Child создан с новой process group и сам зарегистрировал handler. Событие направлено только его PID/group; текущий процесс не получает сигнал.

Временно установить null-handler и убрать егоСамостоятельный пример
<?php
var_dump(sapi_windows_set_ctrl_handler(null, true));
var_dump(sapi_windows_set_ctrl_handler(null, false));
Ожидаемый результат
bool(true)
bool(true)

null заставляет процесс игнорировать CTRL+C, но не CTRL+BREAK. Учебный процесс сразу удаляет настройку; это не рекомендация игнорировать штатную остановку воркера.

Handler должен быть коротким и повторно безопасным. Не начинайте в нём новую долгую интеграцию; зафиксируйте флаг отмены и позвольте основному циклу закрыть ресурсы.

Полный договор вызова

Часть вызоваПолный договор
handlercallable(int $event): void. null игнорирует CTRL+C, но не CTRL+BREAK.
add=true/falseДобавить либо удалить обработчик. Для удаления сохраняйте тот же callable.
Возвратtrue при изменении, false при отказе.
ThreadВ многопоточном окружении возможно только из main thread.

Ошибки и границы. Удаление другого callable не гарантирует снятие нужного handler. null не игнорирует CTRL+BREAK. Сигнальное событие не заменяет deadline процесса.

Версии и платформа. Тест add/remove и isolated CTRL_BREAK выполнены на Windows PHP 8.5.11.

Рядом: sapi_windows_generate_ctrl_event.

Карта полного раздела Miscellaneous.

sapi_windows_vt100_supportПроверить или переключить VT100 control sequences у Windows console stream.

Windows SAPI, PHP 7.2+; nullable enable — PHP 8+ · standard

sapi_windows_vt100_support(resource $stream, ?bool $enable = null): bool

Проверить или переключить VT100 control sequences у Windows console stream.

Скобки после имени запускают вызов; значения внутри — аргументы. Знак = сохраняет возвращённый результат в переменную со знаком $. Функция может вернуть число, строку, массив, true/false либо завершить текущий сценарий. Сначала смотрите минимальный вызов и ожидаемый результат, затем переходите к условиям, функциям и обработке ошибок. Как устроен вызов, параметр и return.

Что произойдёт при вызове

Цвет без мусора в логах
  1. Определить реальный output stream
  2. Спросить VT100 support
  3. При true добавить escape-sequence
  4. При false вывести обычный текст

Первый запуск и развитие задачи

Обычный файл не является Windows console output bufferСамостоятельный пример
<?php
$stream = fopen(__DIR__ . '/output.txt', 'wb');
if ($stream === false) { throw new RuntimeException('file'); }
var_dump(sapi_windows_vt100_support($stream));
var_dump(sapi_windows_vt100_support($stream, true));
fclose($stream);
Ожидаемый результат
bool(false)
bool(false)

Перенаправленный файл не получает ENABLE_VIRTUAL_TERMINAL_PROCESSING. Поэтому цветовые escape-последовательности в лог лучше не записывать.

Закрытый stream вызывает TypeErrorСамостоятельный пример
<?php
$stream = fopen('php://temp', 'w+');
fclose($stream);
try {
    sapi_windows_vt100_support($stream);
} catch (TypeError $error) {
    echo "closed stream rejected\n";
}
Ожидаемый результат
closed stream rejected

Переменная больше не содержит открытый stream resource. Это ошибка типа, а не ответ «VT100 выключен».

Добавлять цвет только при поддержке реальной консолиПример для указанного окружения
<?php
$green = "\033[32m";
$reset = "\033[0m";
$interactive = defined('STDOUT')
    && sapi_windows_vt100_support(STDOUT);
echo $interactive ? $green . 'OK' . $reset . PHP_EOL : "OK\n";

Результат зависит от настоящей консоли/редиректа, поэтому пример проверяется синтаксически. Даже при false сообщение остаётся читаемым без цвета.

При старте PHP уже пытается включить VT100 для STDOUT/STDERR. Приложение не должно считать ANSI-цвет частью бизнес-данных; журнал/JSON всегда остаётся plain.

Полный договор вызова

Часть вызоваПолный договор
streamОткрытый stream, связанный с Windows console output buffer. Redirected file/pipe обычно не поддерживает режим.
enable=nullТолько спрашивает текущее состояние. Nullable с PHP 8.
enable=true/falseПытается включить/выключить ENABLE_VIRTUAL_TERMINAL_PROCESSING.
ВозвратПри query — текущее состояние; при set — success/failure. Windows 10 API может отсутствовать на старой ОС.

Ошибки и границы. Закрытый/non-resource stream даёт TypeError. false у файла — нормальное отсутствие console feature, не авария.

Версии и платформа. Функция использует Windows 10 console API и отсутствует на Unix.

Карта полного раздела Miscellaneous.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.