Перейти к основному содержимому

5.07. Справочник по PHP

Разработчику Архитектору

Справочник по PHP

Языковые конструкции и базовые синтаксические элементы

1.1. Ключевые слова (keywords)

КатегорияСписок ключевых слов
Определение/объявлениеclass, interface, trait, enum, function, const, define, namespace, use, as, static, final, abstract, readonly
Управление доступомpublic, protected, private
Управление потокомif, else, elseif, switch, case, default, while, do, for, foreach, continue, break, goto, match, declare, yield, yield from
Операторыand, or, xor, instanceof, new, clone, exit, die, eval, isset, empty, include, include_once, require, require_once, print, echo, return, throw, try, catch, finally, fn, match
Типизацияarray, callable, bool, float, int, string, iterable, object, mixed, never, null, false, true, void, self, parent, static, ?T (nullable), T|U (union), T&U (intersection — с 8.4), T extends U (generics-подобное ограничение в DocBlock, не в языке)
Атрибуты (с PHP 8.0)#[...] — синтаксис атрибутов; ключевые слова внутри: Attribute (класс), TARGET_* константы для flags

Примечания:

  • match — выражение-аналог switch, возвращает значение, строгое сравнение (===), не требует break.
  • declare(strict_types=1) — директива уровня файла, включает строгую типизацию аргументов/возвратов.
  • readonly — модификатор свойства класса (с PHP 8.1): запись возможна только в конструкторе.

1.2. Синтаксические формы

1.2.1. Типы литералов

ТипПримерыОсобенности
Integer42, -1, 0x2A, 0b101010, 0o52, 1_000_000Поддержка подчёркиваний с PHP 7.4. Основания: 10, 2 (0b), 8 (0o), 16 (0x).
Float3.14, 6.022e23, 1.2e-5, .5, 5.Использует double-precision IEEE 754 (обычно 64-bit).
String'single', "double $var", <<<HEREDOC … HEREDOC, <<<'NOWDOC' … NOWDOCHEREDOC/NOWDOC: отступы влияют на интерпретацию; NOWDOC — без интерполяции.
Booleantrue, false, TRUE, FALSEРегистронезависимо. Приведение: 0, "", [], null, "0"false.
Nullnull, NULLЕдинственное значение типа null.
Array[], [1, 2], ['a' => 1], array(1,2) (устаревшее)Хэш-массив + список; неограниченная вложенность.
Objectnew stdClass, new DateTime(), (object)['a' => 1]Можно кастить из массива.
Resourcefopen('file', 'r')Устаревший тип; с PHP 8.1+ постепенно заменяется на объекты (например, CurlHandle, Socket).
Enum (PHP 8.1+)enum Color: string { case Red = 'r'; }, BackedEnum::from('r')Поддержка UnitEnum, BackedEnum (int/string).

1.2.2. Комментарии

// Однострочный

# Также однострочный (редко используется)

/* Многострочный
Может содержать PHPDoc */

/**
* PHPDoc — для генерации документации и подсказок IDE/анализаторам.
* @param string $name
* @return bool|null
* @throws InvalidArgumentException
*/

1.2.3. Директивы уровня файла

ДирективаПримерНазначение
<?php … ?><?php echo "OK"; ?>Стандартный тег. Закрывающий ?> можно опускать в чистых PHP-файлах.
<? … ?><h1><? echo $title ?></h1>Short open tag — зависит от short_open_tag = On. Не рекомендуется.
<?= … ?><p><?= htmlspecialchars($text) ?></p>Short echo tag — эквивалент <?php echo … ?>. Включён по умолчанию с PHP 5.4+.
<?=То же, что выше.
<script language="php">…</script>Устарело.

1.3. Операторы

1.3.1. Приоритет и ассоциативность (сводка)

Приоритет (высокий → низкий)Операторы
1 (высший)clone, new, (...), [...], ->, ::, ?->, **
2++, --, ~, (int), (string), !, +, - (унарные)
3*, /, %, ** (если не в 1)
4+, -, . (конкатенация)
5<<, >>
6<, <=, >, >=, spaceship (<=>), instanceof
7==, !=, ===, !==, <=>, <>
8&
9^
10|
11&&
12||
13?? (null coalescing), ?: (тернарный), ?-> (nullsafe)
14=, +=, -=, .=, *=, /=, %=, **=, &=, |=, ^=, <<=, >>=
15and
16xor
17 (низший)or

1.3.2. Важные операторы с пояснениями

ОператорПояснение
$a ?? $bВозвращает $a, если не null, иначе $b. Для $a['key'] ?? 'default' — без notice.
$a ?: $bТернарный без middle: эквивалент ($a) ? $a : $b.
$a?->method()Nullsafe method/property access: если $a === null, вернёт null, не вызовет ошибку.
$a <=> $bSpaceship: возвращает -1, 0, 1 — как strcmp. Поддерживает скаляры, массивы (лексикографически), объекты с __toString().
match ($v) { … }Аналог switch, но: выражение (возвращает значение), строгое сравнение, не «проваливается», обрабатывает все ветки.
fn($x) => $x * 2Arrow function: краткая запись анонимной функции, захват переменных по значению (не по ссылке).
...$args (в параметрах/вызове)Spread operator: разворачивает массив или Traversable в аргументы (вызов) или собирает аргументы (параметры — variadic).

Типы и системы типизации

2.1. Встроенные типы (scalar, compound, special)

ГруппаТипы
Scalarbool, int, float, string
Compoundarray, object, callable, iterable
Specialresource, null, mixed, void, never, false, true
Pseudo-types (для документации)number (`int

2.2. Правила приведения типов (явные и неявные)

2.2.1. Явное приведение (casting)

(int) $x            // alias: intval(), (integer)
(float) $x // alias: floatval(), doubleval(), (double), (real)
(string) $x // alias: strval()
(bool) $x // alias: boolval()
(array) $x
(object) $x
(unset) $x // → null (устаревшее, избегать)

2.2.2. Неявное приведение (в контексте операторов/условий)

КонтекстПример приведения
Арифметика"123abc" + 1124 (строка → int по левому префиксу)
Конкатенация123 . "abc""123abc" (int → string)
Логическийif ("0")false; if ("-1")true
Сравнение (==)"123" == 123true; "123e0" == 123true; "0x10" == 16true
Сравнение (===)"123" === 123false (строгая проверка типа)

⚠️ PHP 8.0+ ужесточил некоторые сравнения: например, '0' == '0e123'false (ранее — true, т.к. оба приводились к 0 как float).


Конфигурация: php.ini

3.1. Категории директив

КатегорияПримеры директив
Core PHPengine, short_open_tag, precision, serialize_precision, disable_functions, disable_classes, expose_php, max_execution_time, max_input_time, memory_limit, error_reporting, display_errors, log_errors, error_log
Date/Timedate.timezone, date.default_latitude, date.default_longitude
File Uploadfile_uploads, upload_max_filesize, max_file_uploads, post_max_size
Sessionsession.save_handler, session.save_path, session.name, session.gc_probability, session.cookie_secure, session.cookie_samesite
Mailsendmail_path, mail.add_x_header, mail.log
ExtensionsМногочисленные extension=..., extension_dir, zend_extension=...
OPcacheopcache.enable, opcache.memory_consumption, opcache.max_accelerated_files, opcache.jit
Securityopen_basedir, safe_mode (удалён), allow_url_fopen, allow_url_include
Output Bufferingoutput_buffering, zlib.output_compression
Localeintl.default_locale, mbstring.language, mbstring.internal_encoding

3.2. Важные директивы (с типами значений и диапазонами)

ДирективаТипЗначения / ДиапазонПо умолчанию (PHP 8.3)Комментарий
date.timezonestringЛюбая из списка OlsonUTC (если не задано — warning)Обязательно задавать.
memory_limitint (байты / суффиксы)128M, 256M, -1 (unlimited)128MЛимит памяти на скрипт.
max_execution_timeint (сек)0 (бесконечно), 30, 30030Для CLI — 0 по умолчанию.
error_reportingint (битовая маска)E_ALL, E_ERROR | E_WARNING | E_PARSE, 0E_ALLВ продакшене — без E_NOTICE, E_DEPRECATED.
display_errorsbool / stringOn, Off, stderr, stdoutOff (CLI — stderr)В продакшене — Off.
log_errorsboolOn, OffOn
error_logstring/var/log/php_errors.log, syslogstderr/веб-серверЕсли не задан — в SAPI-лог.
expose_phpboolOn, OffOnДобавляет X-Powered-By заголовок.
allow_url_fopenboolOn, OffOnРазрешает http://, ftp:// в fopen, file_get_contents.
allow_url_includeboolOn, OffOffРазрешает include 'http://...' — крайне небезопасно.
open_basedirstring/var/www:/tmp, """" (без ограничений)Ограничение доступа к ФС.
session.cookie_samesitestringStrict, Lax, NoneLaxЗащита от CSRF.
opcache.enablebool1, 01 (в CLI — 0)Включает OPcache.
opcache.jitstringtracing, function, hot, off; формат CRTO (например, 1255)tracingJIT-компиляция (PHP 8.0+).

Полную таблицу всех 1000+ директив можно получить через php --ini, php -i, или ini_get_all().
Изменить можно в php.ini, .user.ini, .htaccess (если AllowOverride Options=...), или через ini_set() — но не все директивы разрешены к runtime-изменению (см. phpinfo() → «Local/Access»).


Глобальные переменные и суперглобальные массивы

ПеременнаяНазначениеДоступПримеры ключей/значений
$_SERVERИнформация о сервере и запросеЧтение'REQUEST_METHOD', 'QUERY_STRING', 'HTTP_USER_AGENT', 'SCRIPT_FILENAME', 'PHP_SELF', 'argv', 'argc' (CLI)
$_GETПараметры URL (?a=1&b=2)Чтение/запись['a' => '1', 'b' => '2']
$_POSTДанные формы (или JSON, если обработано вручную)Чтение/запись['username' => 'timur']
$_FILESЗагруженные файлыЧтение/запись (осторожно!)['avatar' => ['name'=>'p.jpg','type'=>'image/jpeg','tmp_name'=>'/tmp/phpX','error'=>0,'size'=>12345]]
$_COOKIECookies от клиентаЧтение/запись['session_id' => 'abc123']
$_SESSIONДанные сессии (после session_start())Чтение/запись['user_id' => 42]
$_REQUESTОбъединение $_GET, $_POST, $_COOKIE (порядок — variables_order)Чтение/записьНе рекомендуется из-за неопределённости источника.
$_ENVПеременные окруженияЧтение['HOME' => '/home/timur', 'PATH' => '...']
$GLOBALSВсе глобальные переменные (включая пользовательские)Чтение/запись$GLOBALS['x'] = 1;global $x; $x = 1;
$argc, $argvАргументы CLIЧтение$argv[0] — имя скрипта; $argv[1] — первый аргумент.

⚠️ Все суперглобальные доступны в любом scope (внутри функций — без global).


Встроенные функции — Строки и массивы

Все функции перечислены по категориям, с указанием:

  • сигнатуры (только обязательные параметры, ? — опциональный),
  • минимальной версии PHP, в которой функция появилась (если новее 5.3),
  • краткого пояснения без дублирования документации,
  • особых замечаний: побочные эффекты, locale-зависимость, multibyte-альтернативы.

5.1. Строковые функции (однобайтовые, не-mb_*)

5.1.1. Анализ и проверка

ФункцияСигнатураВерсияПояснение
strlen(string $str)ВсеДлина в байтах. Для UTF-8 — некорректно для символов > U+007F.
mb_strlen(string $str, ?string $encoding = null)4.0.6 (mbstring)Длина в символах (code points). Требует mbstring.
strpos(string $haystack, string|int $needle, int $offset = 0)Позиция первого вхождения (байтовая). Возвращает false, если не найдено.
stripos(...)5.0Регистронезависимый strpos.
strrpos(...), strripos(...)Последнее вхождение.
strstr(string $haystack, string $needle, bool $before_needle = false)Возвращает подстроку от первого вхождения needle до конца. before_needle=true — до него.
stristr(...)Регистронезависимый strstr.
strchr(...)Псевдоним strstr.
strpbrk(string $string, string $characters)5.0Возвращает подстроку от первого символа из набора $characters.
strspn(string $string, string $mask, int $start = 0, ?int $length = null)Длина начального сегмента, состоящего только из символов $mask.
strcspn(...)Длина начального сегмента, не содержащего символов $mask.
ctype_*ctype_alnum, alpha, cntrl, digit, graph, lower, print, punct, space, upper, xdigit — проверки по таблице C locale. Не работают с UTF-8.
is_numeric(mixed $val)Проверяет, является ли значение числовым (включая строки "123", "1.5e3"). Не проверяет тип.
ctype_digit(string $str)Только цифры (0-9), без знака, без точки.

5.1.2. Извлечение и замена

ФункцияСигнатураВерсияПояснение
substr(string $str, int $start, ?int $length = null)Извлечение подстроки (байтово). Отрицательные $start, $length — от конца.
mb_substr(...)4.0.6Символьное извлечение.
substr_replace(string $str, string|array $replacement, int|array $start, int|array $length = ?)4.0.1Замена подстрок по позициям.
str_replace(string|array $search, string|array $replace, string|array $subject, ?int &$count = null)Замена всех вхождений. Регистрозависимая.
str_ireplace(...)5.0Регистронезависимая замена.
strtr(string $str, string|array $from, ?string $to = null)Транслитерация (по символам или по подстрокам). При array — замена ключей на значения.
str_shuffle(string $str)4.3Перемешивает символы строки. Не криптостойко.
strrev(string $str)Обратный порядок байтов. Для UTF-8 — некорректно.
mb_strrev($str, $enc)Обратный порядок символов (не встроена, но реализуется через mb_substr + цикл).

5.1.3. Разделение и объединение

ФункцияСигнатураВерсияПояснение
explode(string $separator, string $str, int $limit = PHP_INT_MAX)Разделение строки по разделителю. Возвращает array.
implode(string $glue, array $pieces)Объединение массива в строку. join() — псевдоним.
str_split(string $str, int $length = 1)5.0Разбиение на массив байтов (или фиксированных блоков по $length байт).
mb_str_split(string $str, int $length = 1, ?string $encoding = null)7.4Разбиение на массив символов (или блоков по $length символов).
preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0)Разделение по регулярному выражению. Флаги: PREG_SPLIT_NO_EMPTY, PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_OFFSET_CAPTURE.
chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n")Вставка $ending каждые $chunklen байт. Используется для base64/MIME.

5.1.4. Форматирование и преобразование регистра

ФункцияСигнатураВерсияПояснение
strtolower(string $str), strtoupper(...)Приведение к нижнему/верхнему регистру по ASCII. Для UTF-8 — некорректно (например, ßSS в немецком).
mb_strtolower(...), mb_strtoupper(...)4.3Регистр по Unicode (требует mbstring).
ucfirst(string $str), lcfirst(...)5.3 (lcfirst)Первый символ — в верхний/нижний регистр.
ucwords(string $str, string $separators = " \t\r\n\f\v")Первый символ каждого слова — в верхний регистр.
trim(string $str, string $characters = " \t\n\r\0\x0B")Удаление пробельных символов с обеих сторон.
ltrim(...), rtrim(...)Слева / справа.
htmlspecialchars(string $str, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, ?string $encoding = null, bool $double_encode = true)5.4+ (флаги)Экранирование <, >, ", ', &. Флаги: ENT_HTML5, ENT_NOQUOTES, ENT_IGNORE (устарело), ENT_SUBSTITUTE (вместо ? при ошибке кодировки).
html_entity_decode(...)Обратная операция.
urlencode(string $str), urldecode(...)Кодирование для query string (application/x-www-form-urlencoded): пробел → +, не-ASCII/зарезервированные → %XX.
rawurlencode(...), rawurldecode(...)RFC 3986: пробел → %20.
base64_encode(string $str), base64_decode(string $str, bool $strict = false)Кодирование в Base64. strict=true — возвращает false при некорректных символах.
quoted_printable_encode(...), quoted_printable_decode(...)5.3Для Content-Transfer-Encoding: quoted-printable.
addcslashes(string $str, string $characters), stripcslashes(...)Экранирование/удаление экранирования C-подобных последовательностей (\n, \t, \x0A, \07).
addslashes(string $str), stripslashes(...)Экранирование ', ", \, NUL. Устаревшее (SQL injection — использовать prepared statements).
nl2br(string $str, bool $use_xhtml = false)Замена \n на или <br />.

5.1.5. Хеширование и криптография (хеш-функции строк)

ФункцияСигнатураВерсияПояснение
md5(string $str, bool $binary = false)MD5 (128-bit). Не использовать для паролей.
sha1(...)SHA-1 (160-bit). Устаревшее.
hash(string $algo, string $data, bool $binary = false)5.1.2Универсальный интерфейс (md5, sha256, sha3-256, blake3, crc32, crc32b, adler32 и др.). Список: hash_algos().
hash_hmac(string $algo, string $data, string $key, bool $binary = false)5.1.2HMAC — хеширование с ключом.
password_hash(string $password, string|int $algo, array $options = [])5.5Рекомендовано для хранения паролей. Алгоритмы: PASSWORD_DEFAULT (bcrypt), PASSWORD_ARGON2I, PASSWORD_ARGON2ID.
password_verify(string $password, string $hash)5.5Проверка пароля. Работает с $2y$, $argon2i$, $argon2id$.

5.2. Многобайтовые строковые функции (mbstring)

Требуется включённое расширение mbstring. По умолчанию: internal_encoding = UTF-8, http_output = UTF-8, regex_encoding = UTF-8.

ФункцияЭквивалентОсобенности
mb_strlen($s, $enc)strlenСимвольная длина.
mb_substr($s, $start, $len, $enc)substrСимвольное извлечение.
mb_strpos($haystack, $needle, $offset, $enc)strposПозиция символа.
mb_strrpos(...), mb_stripos(...), mb_strripos(...)Последнее / регистронезависимое.
mb_strtolower($s, $enc), mb_strtoupper(...)strtolowerUnicode-регистр.
mb_convert_case($s, $mode, $enc)MB_CASE_UPPER, LOWER, TITLE, FOLD, UPPER_SIMPLE, LOWER_SIMPLE.
mb_detect_encoding($s, $encodings = null, bool $strict = false)Попытка определить кодировку. Ненадёжно.
mb_convert_encoding($s, $to, $from)Перекодировка. $from может быть auto.
mb_check_encoding($s, ?string $encoding = null)Проверка валидности кодировки.
mb_http_input(?string $type = null)Кодировка входных данных (G, P, C, S, REQUEST).
mb_http_output(?string $encoding = null)Установка кодировки вывода HTTP.
mb_internal_encoding(?string $encoding = null)Установка внутренней кодировки (для всех mb_*, если $enc не указан).

5.3. Функции для работы с массивами

5.3.1. Создание и базовые операции

ФункцияСигнатураПояснение
array() / []Создание массива.
array_fill(int $start_index, int $num, mixed $value)Заполнение значениями.
array_fill_keys(array $keys, mixed $value)5.2Ассоциативный массив из ключей и одного значения.
range(mixed $start, mixed $end, ?number $step = 1)Последовательность (range(1,5)[1,2,3,4,5]; range('a','e')['a','b','c','d','e']).
compact(string ...$var_names)Создаёт массив из локальных переменных по именам.
extract(array $array, int $flags = EXTR_OVERWRITE, ?string $prefix = null)Извлекает переменные в текущий scope. Опасно — избегать.

5.3.2. Добавление, удаление, изменение

ФункцияСигнатураПояснение
$arr[] = $valДобавление в конец (для индексных массивов).
array_push(array &$arr, mixed ...$values)То же, но можно несколько значений.
array_unshift(array &$arr, mixed ...$values)Добавление в начало (сдвиг индексов).
array_pop(array &$arr)Удаление и возврат последнего элемента.
array_shift(array &$arr)Удаление и возврат первого элемента (сдвиг индексов).
array_splice(array &$arr, int $offset, ?int $length = null, mixed $replacement = [])Удаление/замена сегмента с пересчётом индексов. Возвращает удалённое.
array_replace(array $array, array ...$replacements)5.3Замена элементов по ключам (не рекурсивно).
array_replace_recursive(...)5.3Рекурсивная замена.
array_merge(array ...$arrays)Объединение. Индексные пересчитываются, ассоциативные — перезаписываются.
array_pad(array $arr, int $size, mixed $value)Дополнение до $size элементов (слева — отрицательный $size).

5.3.3. Поиск и фильтрация

ФункцияСигнатураПояснение
in_array(mixed $needle, array $haystack, bool $strict = false)Поиск значения. $strict=true===.
array_search(mixed $needle, array $haystack, bool $strict = false)Возвращает ключ первого вхождения.
array_key_exists(string|int $key, array $array)Проверка наличия ключа (не значения!).
key_exists(...)Псевдоним array_key_exists.
isset($arr[$key])Эквивалентно array_key_exists, но возвращает false, если $arr[$key] === null.
array_filter(array $array, ?callable $callback = null, int $mode = 0)Фильтрация. $callback($value)true/false. $mode: ARRAY_FILTER_USE_KEY, ARRAY_FILTER_USE_BOTH.
array_unique(array $array, int $flags = SORT_STRING)5.2.9+ (флаги)Удаление дубликатов. Флаги: SORT_REGULAR, SORT_NUMERIC, SORT_STRING, SORT_LOCALE_STRING.

5.3.4. Сортировка

ФункцияПояснение
sort(&$arr, $flags)Индексный массив → пересортировка + перенумерация.
rsort(...)Обратная сортировка.
asort(&$arr, $flags)Ассоциативный — сохраняет ключи, сортирует по значениям.
arsort(...)Обратная asort.
ksort(&$arr, $flags)Сортировка по ключам.
krsort(...)Обратная ksort.
usort(&$arr, callable $callback)Пользовательская сортировка по значениям. $callback($a, $b) → `-1
uasort(...), uksort(...)То же, с сохранением ключей / по ключам.
shuffle(&$arr)Перемешивает индексный массив. Не криптостойко.
array_multisort(array &$arr1, mixed $arr1_sort_order, ...)Сложная сортировка нескольких массивов или многомерных структур.

5.3.5. Преобразование и объединение

ФункцияСигнатураПояснение
implode($glue, $arr)Строка из массива.
explode($sep, $str)Массив из строки.
array_chunk(array $arr, int $size, bool $preserve_keys = false)Разбиение на подмассивы по $size элементов.
array_column(array $array, int|string $column_key, ?int|string $index_key = null)5.5Извлечение столбца ($column_key) с опциональным индексированием по $index_key.
array_combine(array $keys, array $values)Создание ассоциативного массива из двух списков.
array_flip(array $arr)Обмен ключей и значений. Только scalar значения.
array_reverse(array $arr, bool $preserve_keys = false)Обратный порядок. По умолчанию — перенумерация индексов.
array_values(array $arr)Только значения, индекс с 0.
array_keys(array $arr, ?mixed $search_value = null, bool $strict = false)Только ключи (все или по значению).
array_map(?callable $callback, array $arr1, array ...$arrays)Применение функции к каждому элементу. Для нескольких массивов — параллельная обработка.
array_reduce(array $arr, callable $callback, mixed $initial = null)Свёртка («фолд»). $callback($carry, $item).
array_walk(array &$arr, callable $callback, ?mixed $userdata = null)Обход с возможностью модификации. $callback(&$value, $key, $userdata).
array_walk_recursive(...)Рекурсивный обход вложенных массивов.

5.3.6. Разное

ФункцияПояснение
count($arr, int $mode = COUNT_NORMAL)Размер массива. COUNT_RECURSIVE — рекурсивный подсчёт.
sizeof(...)Псевдоним count.
empty($arr)Эквивалентно !count($arr) или !$arr.
is_array($var)Проверка типа.
array_is_list(array $arr)8.1
list($a, $b) = $arr

Встроенные функции — Дата и время

6.1. Основные функции

ФункцияСигнатураПояснение
time()Текущее Unix time (секунды с 1970-01-01 00:00:00 UTC).
microtime(bool $as_float = false)Микросекунды. $as_float=truefloat, иначе "0.123456 1712345678".
date(string $format, ?int $timestamp = null)Форматирование времени. $format — как в strftime, но свои коды (Y-m-d H:i:s).
gmdate(...)То же, но в UTC.
strtotime(string $datetime, ?int $base_timestamp = null)Парсинг даты/времени в timestamp. Поддерживает "+1 day", "next Monday", "2025-11-22".
date_create(?string $datetime = "now", ?DateTimeZone $timezone = null)5.2Создание DateTime. Алиас new DateTime(...).
date_format(DateTimeInterface $object, string $format)5.2DateTime::format(...).
date_diff(DateTimeInterface $d1, DateTimeInterface $d2, bool $absolute = false)5.3Разница → DateInterval.
getdate(?int $timestamp = null)Возвращает ассоциативный массив (seconds, minutes, hours, mday, wday, mon, year, yday, weekday, month, 0 — timestamp).
gettimeofday(bool $as_float = false)Подробности времени (сек, мкс, часовой пояс).
localtime(?int $timestamp = null, bool $associative = false)Массив из 9 элементов (год+1900, месяц 0-11, день 1-31 и т.д.).

6.2. Часовые пояса

ФункцияПояснение
date_default_timezone_set(string $timezone)Установка часового пояса (обязательно, иначе warning).
date_default_timezone_get()Текущий часовой пояс.
timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null)Список всех зон (по стране или группе: AFRICA, AMERICA, UTC, EUROPE и др.).
timezone_open(string $timezone)Создание DateTimeZone. Алиас new DateTimeZone(...).
timezone_name_get(DateTimeZone $obj)Получение имени зоны.
timezone_offset_get(DateTimeZone $obj, DateTimeInterface $datetime)Смещение от UTC в секундах (с учётом DST).

6.3. Классы DateTime, DateTimeImmutable, DateInterval, DatePeriod

КлассОсобенности
DateTimeМутирующий.
DateTimeImmutableВозвращает новый объект при изменении. Рекомендуется.
DateIntervalИнтервал (P1Y2M3DT4H5M6S). Создание: DateInterval::createFromDateString("1 day"), new DateInterval("P1D").
DatePeriodПоследовательность дат: `new DatePeriod($start, $interval, $end

Пример:

$dt = new DateTimeImmutable('2025-11-22 10:00:00', new DateTimeZone('Europe/Moscow'));
$dt2 = $dt->add(new DateInterval('P1M')); // +1 месяц
echo $dt2->format('c'); // 2025-12-22T10:00:00+03:00

Функции для работы с файлами и файловой системой

Все функции работают с локальной ФС или потоками (php://, data://, http:// при allow_url_fopen=On).
Стандартный подход — работа с ресурсами (resource) до PHP 8.0, с PHP 8.1+ — объектами (SplFileObject, CurlHandle, Socket, StreamWrapper).
Для работы с правами и метаданными — stat(), lstat(), fileperms(), fileowner(), filegroup().


7.1. Открытие, чтение, запись, закрытие

ФункцияСигнатураПояснение
fopen(string $filename, string $mode, bool $use_include_path = false, ?resource $context = null)Открытие файла/потока. Возвращает resource (до PHP 8.0) или объект resource (внутренний — без класса). Режимы: r, r+, w, w+, a, a+, x, x+, c, c+; суффиксы: b (binary), t (text — игнорируется), e (close-on-exec, PHP 7.3+).
fclose(resource $stream)Закрытие ресурса.
file_get_contents(string $filename, bool $use_include_path = false, ?resource $context = null, int $offset = 0, ?int $length = null)4.3Чтение всего файла в строку. Поддерживает URL.
file_put_contents(string $filename, mixed $data, int $flags = 0, ?resource $context = null)5.0Запись строки/массива в файл. $data приводится к строке (implode('', $data) для массива). Флаги: FILE_USE_INCLUDE_PATH, FILE_APPEND, LOCK_EX.
readfile(string $filename, bool $use_include_path = false, ?resource $context = null)Чтение и вывод содержимого файла (в stdout). Возвращает число байт.
fpassthru(resource $stream)Вывод остатка потока (после текущей позиции). Полезно после fseek.
fgets(resource $stream, ?int $length = null)Чтение строки (до \n, \r, \r\n). $length — макс. байт (включая завершающий нуль в C, но PHP это скрывает).
fgetss(resource $stream, ?int $length = null, ?string $allowable_tags = null)Чтение строки + удаление HTML-тегов (устарело с PHP 7.3, удалено в 8.0).
fgetcsv(resource $stream, ?int $length = null, string $separator = ",", string $enclosure = '"', string $escape = "\\")Чтение CSV-строки → массив. $length игнорируется с PHP 5.1.
fputcsv(resource $stream, array $fields, string $separator = ",", string $enclosure = '"', string $escape = "\\", string $eol = "\n")5.1Запись CSV-строки.
fwrite(resource $stream, string $data, ?int $length = null) / fputs(...)Запись строки. $length — макс. байт для записи. Возвращает число записанных байт.
fread(resource $stream, int $length)Чтение $length байт. Может вернуть меньше (например, при конце файла или нет blocking-режиме).

7.2. Позиционирование в потоке

ФункцияПояснение
ftell(resource $stream)Текущая позиция (байты от начала).
fseek(resource $stream, int $offset, int $whence = SEEK_SET)Установка позиции. $whence: SEEK_SET (от начала), SEEK_CUR (от текущей), SEEK_END (от конца). Возвращает 0 при успехе, -1 — ошибка.
rewind(resource $stream)Эквивалент fseek($stream, 0).

7.3. Проверки состояния

ФункцияПояснение
feof(resource $stream)Достигнут конец файла. Не использовать как условие цикла — проверять после fread/fgets.
fgetc(resource $stream)Чтение одного байта.
stream_get_meta_data(resource $stream)Метаданные: timed_out, blocked, eof, wrapper_type, stream_type, mode, unread_bytes, seekable.
stream_get_contents(resource $stream, ?int $length = -1, int $offset = -1)Чтение остатка потока (или $length байт) с опционального $offset.

7.4. Работа с файлами как с массивами

ФункцияПояснение
file(string $filename, int $flags = 0, ?resource $context = null)Чтение файла в массив строк. $flags: FILE_IGNORE_NEW_LINES, FILE_SKIP_EMPTY_LINES, FILE_USE_INCLUDE_PATH.
parse_ini_file(string $filename, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL)4.2
parse_ini_string(string $ini, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL)5.3

7.5. Информация о файле и ФС

ФункцияПояснение
file_exists(string $filename)Существует ли файл/директория.
is_file(string $filename), is_dir(...), is_link(...), is_readable(...), is_writable(...), is_executable(...)Проверки типа и прав.
stat(string $filename)Массив метаданных: [0]dev, [1]ino, [2]mode, [3]nlink, [4]uid, [5]gid, [6]rdev, [7]size, [8]atime, [9]mtime, [10]ctime, [11]blksize, [12]blocks]. Аналог lstat для симлинков.
lstat(...)То же, но для симлинка (не цели).
fileatime(...), filemtime(...), filectime(...), filesize(...)Удобные обёртки над stat.
fileperms(string $filename)Права в восьмеричном виде (например, 0644int(420)). Форматирование: decoct(fileperms($f) & 0777).
fileowner(...), filegroup(...)UID/GID владельца.
pathinfo(string $path, int $flags = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME)Разбор пути: dirname, basename, extension, filename (без расширения).
basename(string $path, ?string $suffix = null)Имя файла (с удалением $suffix, если совпадает).
dirname(string $path, int $levels = 1)Родительская директория (levels — вложенность).

7.6. Операции с файлами и директориями

ФункцияПояснение
copy(string $from, string $to, ?resource $context = null)Копирование файла.
rename(string $from, string $to, ?resource $context = null)Переименование/перемещение.
unlink(string $filename)Удаление файла.
mkdir(string $pathname, int $mode = 0777, bool $recursive = false)Создание директории. $mode — права (маскируются umask).
rmdir(string $dirname)Удаление пустой директории.
tempnam(string $dir, string $prefix)Создание временного файла с уникальным именем.
tmpfile()Создание временного анонимного файла (удаляется при fclose или завершении скрипта).
realpath(string $path)Преобразование в абсолютный путь (с разрешением .., ., симлинков). Возвращает false, если путь не существует.
glob(string $pattern, int $flags = 0)Поиск файлов по шаблону (wildcard: *, ?, [...]). $flags: GLOB_MARK, GLOB_NOSORT, GLOB_NOCHECK, GLOB_BRACE, GLOB_ONLYDIR.

7.7. Работа с директориями

ФункцияПояснение
opendir(string $directory, ?resource $context = null)Открытие директории → resource.
readdir(resource $dir_handle)Чтение имени следующего файла/директории. Возвращает false в конце.
rewinddir(resource $dir_handle)Сброс позиции в начало.
closedir(resource $dir_handle)Закрытие.
scandir(string $directory, int $sorting_order = SCANDIR_SORT_ASCENDING, ?resource $context = null)Чтение всех имён → массив. $sorting_order: ASCENDING, DESCENDING, NONE.

Альтернатива — DirectoryIterator, RecursiveDirectoryIterator, FilesystemIterator (SPL).


7.8. Потоки (streams) и контексты

ЭлементПояснение
stream_context_create(array $options = [], array $params = [])Создание контекста для fopen, file_get_contents и др.
stream_wrapper_register(string $protocol, string $class, int $flags = 0)Регистрация пользовательского обработчика протокола (реализует stream_wrapper-интерфейс).
stream_select(array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds)Мультиплексирование ввода/вывода (аналог select(2)).
stream_socket_client(string $address, ?int &$errno = null, ?string &$errstr = null, ?float $timeout = null, int $flags = STREAM_CLIENT_CONNECT, ?resource $context = null)Создание клиентского сокета.
stream_socket_server(...)Серверный сокет.
stream_copy_to_stream(resource $from, resource $to, ?int $length = null, int $offset = 0)Копирование между потоками.

Пример контекста для HTTP:

$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode($data),
'timeout' => 10,
'ignore_errors' => true,
]
]);
$result = file_get_contents('https://api.example.com', false, $context);

Сетевые функции

8.1. HTTP и URL

ФункцияПояснение
parse_url(string $url, int $component = -1)Разбор URL → компоненты (scheme, host, port, user, pass, path, query, fragment). $component: PHP_URL_SCHEME, _HOST, _PORT, _USER, _PASS, _PATH, _QUERY, _FRAGMENT.
http_build_query(array|object $data, string $numeric_prefix = "", ?string $arg_separator = null, int $encoding_type = PHP_QUERY_RFC1738)5.1.2
get_headers(string $url, bool $associative = false, ?resource $context = null)
get_meta_tags(string $filename, bool $use_include_path = false)

8.2. Сокеты (низкоуровневые)

ФункцияПояснение
fsockopen(string $hostname, ?int $port = null, ?int &$errno = null, ?string &$errstr = null, ?float $timeout = null)TCP/SSL-соединение. Возвращает resource.
pfsockopen(...)Персистентное соединение (между запросами — в модульном SAPI).
socket_create(int $domain, int $type, int $protocol)
socket_connect(resource $socket, string $address, ?int $port = null)
socket_write(...), socket_read(...)
socket_close(...)

Сокеты требуют расширения sockets. fsockopen работает поверх streams.

8.3. cURL (расширение curl)

ФункцияПояснение
curl_init(?string $url = null)Создание CurlHandle.
curl_setopt(CurlHandle $ch, int $option, mixed $value)Установка опции. Ключевые: CURLOPT_URL, RETURNTRANSFER, POST, POSTFIELDS, HTTPHEADER, SSL_VERIFYPEER, TIMEOUT, FOLLOWLOCATION, USERAGENT, PROXY.
curl_exec(CurlHandle $ch)Выполнение. Возвращает string (если RETURNTRANSFER=true) или bool.
curl_getinfo(CurlHandle $ch, ?int $option = null)Информация о запросе: HTTP_CODE, TOTAL_TIME, SIZE_DOWNLOAD, REDIRECT_URL и др.
curl_error(CurlHandle $ch)Сообщение об ошибке.
curl_close(CurlHandle $ch)Закрытие.

Рекомендации:

  • Использовать curl_setopt_array() для множества опций.
  • Всегда проверять curl_exec() === false и curl_error().
  • Для параллельных запросов — curl_multi_init().

Математические функции и генерация случайных чисел

9.1. Арифметика и округление

ФункцияПояснение
abs(mixed $num)Модуль.
ceil(float $num)Округление вверх.
floor(...)Вниз.
round(float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP)Округление. $mode: HALF_UP, HALF_DOWN, HALF_EVEN, HALF_ODD.
intval(mixed $value, int $base = 10)Приведение к int.
floatval(...), strval(...), boolval(...)
is_nan(float $val), is_infinite(...)Проверка специальных значений.
fmod(float $x, float $y)Остаток от деления (для float).

9.2. Функции

ФункцияПояснение
sqrt($x), pow($base, $exp), exp($x), log($x, $base = M_E), log10($x), log1p($x)Стандартные функции.
sin($x), cos(...), tan(...), asin(...), acos(...), atan(...), atan2($y, $x)Тригонометрия (аргумент — радианы).
pi()π.
hypot($x, $y)Гипотенуза (sqrt(x*x + y*y)).

9.3. Случайные числа

ФункцияВерсияПояснение
rand(int $min = 0, int $max = getrandmax())Устаревшая (линейный конгруэнтный генератор).
mt_rand(...)Mersenne Twister (лучше rand, но не криптостойкий).
random_int(int $min, int $max)7.0Криптографически стойкий целочисленный генератор (CSPRNG). Блокирующий.
random_bytes(int $length)7.0CSPRNG — байты.
getrandmax()Макс. значение для rand().

Всегда использовать random_int/random_bytes для:

  • генерации токенов,
  • сессионных ID,
  • паролей,
  • nonce, CSRF-токенов.

Регулярные выражения (PCRE)

PHP использует библиотеку PCRE2 (с PHP 7.3+). Все функции — preg_*.

10.1. Основные функции

ФункцияСигнатураПояснение
preg_match(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0)Поиск первого совпадения. $flags: PREG_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL.
preg_match_all(...)Все совпадения → 2D-массив $matches.
preg_replace(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, ?int &$count = null)Замена. Поддерживает callback: preg_replace_callback($pattern, callable $callback, ...).
preg_split(...)Разделение по регулярке.
preg_grep(string $pattern, array $array, int $flags = 0)Фильтрация массива по регулярке.
preg_quote(string $str, ?string $delimiter = null)Экранирование метасимволов. $delimiter — символ разделителя (например, /).

10.2. Синтаксис шаблонов (кратко)

  • Разделитель: любой символ (/, #, ~, @). Пример: '/\d+/', '~\w+~'.

  • Модификаторы (после закрывающего разделителя):

    • i — регистронезависимость,
    • m — многострочный режим (^, $ — начало/конец строки),
    • s. включает \n,
    • u — UTF-8 (обязателен для Unicode),
    • x — расширенный синтаксис (игнорировать пробелы, комментарии #),
    • A — только начало строки (\A),
    • D$ не совпадает с \n в конце,
    • J — разрешить дублирование имён захватов,
    • S — изучение шаблона (оптимизация).
  • Квантификаторы: *, +, ?, {n}, {n,}, {n,m}; ленивые: *?, +?, ??.

  • Группы:

    • (pattern) — захватывающая,
    • (?:pattern) — незахватывающая,
    • (?P<name>pattern) — именованная,
    • (?|...) — сброс нумерации внутри веток,
    • (?>...) — атомарная группировка.
  • Опережающие/ретроспективные проверки:

    • (?=...) — позитивный просмотр вперёд,
    • (?!...) — негативный,
    • (?<=...) — позитивный ретроспективный,
    • (?<!...) — негативный.

10.3. Обратные ссылки и замена

  • В preg_replace: $0, $1, $2, ${1}, $+, ${name}.
  • В callback-функции: $matches[0], $matches[1], $matches['name'].

Пример:

$text = 'Timur Vladislavovich';
$result = preg_replace_callback(
'/(\w+)\s+(\w+)/',
fn($m) => strtoupper($m[2]) . ', ' . $m[1],
$text
); // "VLADISLAVOVICH, Timur"

10.4. JIT-компиляция PCRE

  • С PHP 7.3 PCRE2 поддерживает JIT.
  • Включается через pcre.jit=1 в php.ini.
  • Ускоряет сложные регулярки (до 5–10×), но требует памяти.
  • Проверить: preg_match('/(*NO_JIT)./D', '', $matches, PREG_OFFSET_CAPTURE) — если ошибка, JIT недоступен.

Функции для работы с JSON, XML и сериализацией

11.1. JSON

11.1.1. Основные функции

ФункцияСигнатураВерсияПояснение
json_encode(mixed $value, int $flags = 0, int $depth = 512)Кодирование в JSON. Возвращает string или false при ошибке.
json_decode(string $json, ?bool $assoc = null, int $depth = 512, int $flags = 0)Декодирование. $assoc=truearray, иначе stdClass.
json_last_error()5.3Код последней ошибки (JSON_ERROR_NONE, _DEPTH, _STATE_MISMATCH, _CTRL_CHAR, _SYNTAX, _UTF8, _RECURSION, _INF_OR_NAN, _INVALID_PROPERTY_NAME).
json_last_error_msg()5.5Текстовое сообщение об ошибке.

11.1.2. Флаги json_encode

ФлагЗначениеЭффект
JSON_HEX_TAG1<<0<\u003C, >\u003E
JSON_HEX_AMP1<<1&\u0026
JSON_HEX_APOS1<<2'\u0027
JSON_HEX_QUOT1<<3"\u0022
JSON_FORCE_OBJECT1<<4Пустой массив → {}, не []
JSON_NUMERIC_CHECK1<<5Строки-числа → числа (например, "123"123)
JSON_BIGINT_AS_STRING1<<6Числа > 2^53-1 → строки (иначе потеря точности)
JSON_PRETTY_PRINT1<<7Форматированный вывод (отступы, переносы)
JSON_UNESCAPED_SLASHES1<<8Не экранировать /
JSON_UNESCAPED_UNICODE1<<9Не экранировать не-ASCII символы
JSON_PRESERVE_ZERO_FRACTION7.11.01.0, не 1
JSON_INVALID_UTF8_IGNORE7.2Игнорировать некорректные UTF-8 последовательности
JSON_INVALID_UTF8_SUBSTITUTE7.2Заменять на \uFFFD
JSON_THROW_ON_ERROR7.3Генерировать JsonException вместо false

11.1.3. Флаги json_decode

ФлагЗначениеЭффект
JSON_BIGINT_AS_STRING1<<6Большие целые → строки
JSON_OBJECT_AS_ARRAY1<<8Объекты → ассоциативные массивы (даже при $assoc=false)
JSON_THROW_ON_ERROR7.3Выбрасывать JsonException при ошибке

11.1.4. Обработка ошибок (рекомендовано с PHP 7.3+)

try {
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
// $e->getMessage(), $e->getCode()
}

11.2. XML

11.2.1. DOM (Document Object Model)

КлассНазначение
DOMDocumentКорневой документ. Методы: load($file), loadXML($str), save($file), saveXML(), createElement(...), createTextNode(...), getElementsByTagName(...), getElementById(...), documentElement, firstChild.
DOMElementЭлемент. Свойства: tagName, textContent, attributes; методы: getAttribute(...), setAttribute(...), removeAttribute(...), appendChild(...), removeChild(...).
DOMAttrАтрибут. Свойства: name, value, ownerElement.
DOMNodeListКоллекция узлов (например, результат getElementsByTagName). Доступ: $list->item($i), $list->length.
DOMXPathXPath-запросы: $xpath = new DOMXPath($doc); $nodes = $xpath->query('//book[@category="web"]');

Пример:

$doc = new DOMDocument();
$doc->loadXML('<root><item id="1">A</item></root>');
$xpath = new DOMXPath($doc);
$item = $xpath->query('//item[@id="1"]')->item(0);
echo $item->textContent; // "A"

11.2.2. SimpleXML

Класс/функцияПояснение
simplexml_load_string(string $data, ?string $class_name = "SimpleXMLElement", int $options = 0, string $namespace_or_prefix = "", bool $is_prefix = false)Загрузка XML из строки → SimpleXMLElement.
simplexml_load_file(string $filename, ...)Из файла.
new SimpleXMLElement($xml, $options, $data_is_url = false)Конструктор.
asXML(?string $filename = null)Сохранение в строку/файл.
$el['attr']Доступ к атрибутам.
$el->childДоступ к дочерним элементам (возвращает SimpleXMLElement или null).
$el->children()Все дочерние элементы.
$el->attributes()Все атрибуты.
$el->xpath(string $path)XPath-запрос → массив SimpleXMLElement.

Пример:

$xml = simplexml_load_string('<root><a x="1">text</a></root>');
echo $xml->a['x']; // "1"
echo (string)$xml->a; // "text"

⚠️ SimpleXML — для простых XML. Для сложных сценариев (редактирование, пространства имён, валидация) — использовать DOM.

11.2.3. XMLReader (потоковый парсер, low memory)

МетодПояснение
open(string $URI)Открытие XML-файла/URL.
read()Чтение следующего узла. Возвращает bool.
nodeTypeТип узла: XMLReader::ELEMENT, END_ELEMENT, TEXT, CDATA, COMMENT, PI, DTD, DOC, DOC_TYPE.
name, value, isEmptyElement, hasValue, depthМетаданные текущего узла.
getAttribute(string $name)Атрибут текущего элемента.
expand()Преобразование текущего узла в DOMNode (для передачи в DOM).

Пример (итерация по элементам):

$reader = new XMLReader();
$reader->open('data.xml');
while ($reader->read()) {
if ($reader->nodeType === XMLReader::ELEMENT && $reader->name === 'item') {
$dom = new DOMDocument();
$node = $reader->expand($dom);
// обработка $node как DOMElement
}
}
$reader->close();

11.2.4. XMLWriter (потоковая генерация)

МетодПояснение
openMemory() / openUri(string $uri)Буфер в памяти / запись в файл.
startDocument(string $version = "1.0", ?string $encoding = null, ?string $standalone = null)
startElement(string $name), endElement()Начало/конец элемента.
writeElement(string $name, ?string $content = null)Самозакрывающийся или с содержимым.
writeAttribute(string $name, string $value)Атрибут (должен быть вызван после startElement).
text(string $content)Текстовое содержимое.
flush(?bool $empty = true)Получение результата (openMemory) или сброс буфера.

11.3. Сериализация

ФункцияПояснение
serialize(mixed $value)Преобразование в строку, пригодную для хранения. Поддерживает: array, object, resource (но восстановление невозможно — становится NULL).
unserialize(string $data, array $options = [])Обратное преобразование. $options: allowed_classes (массив имён классов или false), max_depth (PHP 7.4+).
__sleep() / __wakeup()Магические методы объекта: __sleep() → список свойств для сериализации; __wakeup() — после десериализации.

Безопасность:

  • Никогда не десериализуйте ненадёжные данные без allowed_classes.
  • Рассмотрите альтернативы: JSON, MessagePack, Protobuf.

Пример безопасной десериализации:

$data = unserialize($str, ['allowed_classes' => ['MyClass', 'DateTime']]);

11.3.1. Альтернативы

ФорматРасширениеФункции
MessagePackmsgpackmsgpack_pack(), msgpack_unpack()
IGBinaryigbinaryigbinary_serialize(), igbinary_unserialize() (используется в Memcached/Redis для сериализации)
WDDXwddxwddx_serialize_value(), wddx_deserialize() (устаревшее)

Обработка ошибок, исключения и отладка

12.1. Типы ошибок

УровеньКонстантаЗначениеДействие по умолчанию
ОшибкаE_ERROR1Завершение скрипта
ПредупреждениеE_WARNING2Продолжение
УведомлениеE_NOTICE4Продолжение
Ошибка при компиляцииE_COMPILE_ERROR64Завершение
Предупреждение при компиляцииE_COMPILE_WARNING128Продолжение
Ошибка в coreE_CORE_ERROR16Завершение
Предупреждение в coreE_CORE_WARNING32Продолжение
User errorE_USER_ERROR256Завершение
User warningE_USER_WARNING512Продолжение
User noticeE_USER_NOTICE1024Продолжение
StrictE_STRICT2048Продолжение (рекомендации)
Recoverable errorE_RECOVERABLE_ERROR4096Продолжение (но может стать фатальной)
DeprecatedE_DEPRECATED8192Продолжение
User deprecatedE_USER_DEPRECATED16384Продолжение

С PHP 8.0+ E_STRICT включён в E_ALL.

12.2. Настройка обработки

ФункцияПояснение
error_reporting(int $error_level = ?)Установка уровня сообщений. Например: error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE).
set_error_handler(callable $callback, int $error_levels = E_ALL)Установка пользовательского обработчика для нефатальных ошибок. Возвращает предыдущий обработчик.
restore_error_handler()Возврат к предыдущему.
set_exception_handler(callable $callback)Обработчик неперехваченных исключений.
restore_exception_handler()
trigger_error(string $message, int $error_level = E_USER_NOTICE)Генерация пользовательской ошибки.

Пример обработчика:

set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
if (!(error_reporting() & $errno)) return false;
error_log("[$errno] $errstr in $errfile:$errline");
return true; // ошибка обработана
});

12.3. Исключения

КлассНазначение
ExceptionБазовый класс.
Error(PHP 7.0+) Ошибки движка (например, TypeError, ParseError, ArgumentCountError). Наследует Throwable.
TypeError, ValueError, ArgumentCountError, ArithmeticError, DivisionByZeroErrorКонкретные ошибки типизации и логики.
PDOExceptionОшибки PDO.
JsonExceptionОшибки JSON (при JSON_THROW_ON_ERROR).

Иерархия:

Throwable
├── Exception
│ ├── RuntimeException
│ ├── LogicException
│ └── ...
└── Error
├── TypeError
├── ParseError
└── ...

Блок try/catch:

try {
// код
} catch (TypeError $e) {
// обработка
} catch (Exception|Error $e) { // PHP 8.0+ union types
// универсальный перехват
} finally {
// всегда выполняется
}

12.4. Отладка

ФункцияПояснение
debug_backtrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit = 0)Стек вызовов. $options: PROVIDE_OBJECT, IGNORE_ARGS.
debug_print_backtrace(int $options = 0, int $limit = 0)Печать стека в stdout.
var_dump(mixed ...$vars)Детальный вывод типа и значения.
print_r(mixed $var, bool $return = false)Человекочитаемый вывод (для array, object).
get_defined_vars()Массив всех локальных переменных.
get_declared_classes(), get_declared_interfaces(), get_declared_traits()Списки определённых сущностей.
get_loaded_extensions()Список загруженных расширений.

12.4.1. Xdebug (опционально, но стандарт де-факто)

ФункцияПояснение
xdebug_info()Информация о состоянии Xdebug (PHP 8.1+).
xdebug_break()Принудительная остановка (breakpoint).
xdebug_var_dump(...)Улучшенный var_dump с цветами и ссылками.

Для удалённого дебага — настроить xdebug.client_host, xdebug.client_port, IDE (PhpStorm, VSCode + PHP Debug).


Сессии, cookies и безопасность

13.1. Сессии

ФункцияПояснение
session_start(array $options = [])Запуск сессии. $options: use_cookies, use_only_cookies, name, id, cache_limiter, cache_expire, use_strict_mode, sid_bits_per_character, sid_length, lazy_write.
$_SESSIONГлобальный массив данных сессии.
session_id(?string $id = null)Получение/установка ID сессии.
session_name(?string $name = null)Имя сессии (используется в cookie PHPSESSID).
session_regenerate_id(bool $delete_old_session = false)Смена ID (защита от fixation).
session_destroy()Удаление данных сессии на сервере (не удаляет cookie!).

13.1.1. Настройки php.ini (session.*)

ДирективаЗначение по умолчаниюКомментарий
session.save_handlerfilesfiles, memcached, redis, user
session.save_path""Путь для files; tcp://host:port?weight=1 для memcached
session.cookie_secure0Только HTTPS
session.cookie_httponly1Доступ только через HTTP (не JS)
session.cookie_samesiteLaxStrict, Lax, None
session.use_strict_mode1 (8.0+)Запрет инициализации сессии по несуществующему ID
session.sid_length32Длина ID (минимум 22)
session.sid_bits_per_character54 (0-9a-f), 5 (0-9a-v), 6 (0-9a-zA-Z,-)

13.2. Cookies

ФункцияСигнатураПояснение
setcookie(string $name, ?string $value = "", array|int $options = [])7.3+Установка cookie. $options: expires, path, domain, secure, httponly, samesite (Strict, Lax, None).
setrawcookie(...)Без urldecode при получении.
$_COOKIEПолучение cookies.

Пример безопасного cookie:

setcookie('token', $token, [
'expires' => time() + 86400,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);

13.3. Безопасность

РекомендацияМетод реализации
SQL-инъекцииИспользовать prepared statements (PDO::prepare, mysqli_stmt_prepare). Никогда не интерполировать данные в запрос.
XSSЭкранировать вывод: htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8').
CSRFГенерировать уникальный токен (random_bytes(32)), хранить в сессии, проверять при POST.
IDORПроверять права доступа на каждый запрос (не доверять user_id=123 в URL).
ЛогиНе записывать пароли, токены, персональные данные в логи.
Заголовкиheader('X-Content-Type-Options: nosniff'), X-Frame-Options: DENY, Content-Security-Policy: default-src 'self'.

Пример CSP:

header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';");

Расширения: PDO, MySQLi, OPcache, FFI, Intl, MBString, GMP

14.1. PDO (PHP Data Objects)

КлассНазначение
PDOСоединение. Конструктор: new PDO($dsn, $user, $pass, $options).
PDOStatementРезультат запроса. Методы: execute(), fetch(), fetchAll(), rowCount(), bindParam(), bindValue().

Пример:

$pdo = new PDO(
'mysql:host=localhost;dbname=test;charset=utf8mb4',
$user, $pass,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '+00:00'"
]
);

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch();

14.1.1. DSN-форматы

ДрайверDSN
MySQLmysql:host=localhost;port=3306;dbname=test;charset=utf8mb4
PostgreSQLpgsql:host=localhost;port=5432;dbname=test;user=...;password=...
SQLitesqlite:/path/to/file.db или sqlite::memory:
SQL Serversqlsrv:server=localhost;database=test

14.1.2. Атрибуты соединения (PDO::ATTR_*)

АтрибутЗначение по умолчаниюНазначение
ATTR_ERRMODEERRMODE_SILENTSILENT, WARNING, EXCEPTION
ATTR_DEFAULT_FETCH_MODEFETCH_BOTHASSOC, NUM, BOTH, OBJ, LAZY
ATTR_EMULATE_PREPAREStrue (для некоторых драйверов)Эмуляция prepared statements на стороне PHP. Выключить для mysql при использовании LIMIT ?.
MYSQL_ATTR_USE_BUFFERED_QUERYtrueБуферизованные результаты (можно rowCount()).

14.2. MySQLi

ОбъектНазначение
mysqliСоединение (new mysqli($host, $user, $pass, $db, $port)).
mysqli_stmtПодготовленное выражение ($stmt = $mysqli->prepare($sql)).

Пример:

$mysqli = new mysqli('localhost', $user, $pass, 'test');
$stmt = $mysqli->prepare('SELECT name FROM users WHERE id = ?');
$stmt->bind_param('i', $id); // i = integer
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();

14.3. OPcache

ДирективаЗначениеПояснение
opcache.enable1Включить кэширование opcode.
opcache.memory_consumption128 (МБ)Память под скрипты.
opcache.max_accelerated_files10000Макс. число кэшируемых скриптов (должно быть простым числом больше ожидаемого количества).
opcache.validate_timestamps1Проверять изменения файлов (в продакшене — 0, обновлять через opcache_reset()).
opcache.revalidate_freq2 (сек)Интервал проверки (если validate_timestamps=1).
opcache.jittracingJIT-компиляция. Формат CRTO, например: 1255C=1 (CPU-specific), R=2 (register allocator), T=5 (tracing), O=5 (optimisation level).
opcache.jit_buffer_size0Размер буфера JIT (например, 100M).

Функции:

  • opcache_get_status() — статус кэша.
  • opcache_get_configuration() — текущие настройки.
  • opcache_reset() — сброс кэша.
  • opcache_invalidate(string $path, bool $force = false) — сброс одного файла.

14.4. FFI (Foreign Function Interface, PHP 7.4+)

КлассНазначение
FFIРабота с нативными библиотеками.

Пример (вызов strlen из libc):

$ffi = FFI::cdef("size_t strlen(const char *s);", "libc.so.6");
$len = $ffi->strlen("Hello");

Рекомендации:

  • Использовать только при отсутствии PHP-реализации.
  • Обеспечить совместимость ABI (x86_64, glibc версия).
  • Избегать в веб-приложениях (риск падения процесса).

14.5. Intl (интернационализация)

Функция/КлассПояснение
IntlCharРабота с Unicode code points.
NormalizerНормализация строк (NFC, NFD, NFKC, NFKD).
CollatorЛокализованная сортировка.
NumberFormatterФорматирование чисел/валют (en_US: 1,234.56; ru_RU: 1 234,56).
MessageFormatterИнтерполяция с учётом склонения ({0, plural, one{# book} other{# books}}).
IntlDateFormatterФорматирование дат по локали.

Пример:

$fmt = new NumberFormatter('ru_RU', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.56, 'RUB'); // "1 234,56 ₽"

14.6. MBString (многобайтовые строки)

См. Часть 5.2.


14.7. GMP (произвольная точность)

ФункцияПояснение
gmp_init(mixed $num, int $base = 0)Создание GMP-числа.
gmp_add($a, $b), sub, mul, div_q, mod, pow, sqrt, gcd, abs, neg, cmpАрифметика.
gmp_strval(GMP $num, int $base = 10)Преобразование в строку.

Пример:

$a = gmp_init('123456789012345678901234567890');
$b = gmp_pow($a, 2);
echo gmp_strval($b); // 152415787532388367504953515625...

CLI, параметры запуска, SAPI (FPM, Apache, CLI)

15.1. CLI (Command Line Interface)

15.1.1. Параметры запуска (php [опции] [скрипт] [аргументы])

ОпцияНазначение
-f <файл>Выполнить файл (по умолчанию, если указан путь — не требуется).
-r <код>Выполнить PHP-код напрямую (однострочный). Экранирование кавычек обязательно.
-B <код>Выполнить до основного скрипта.
-R <код>Выполнить для каждой строки ввода ($argn, $argf). Аналог while(fgets(STDIN)).
-E <код>Выполнить после основного скрипта.
-S <addr:port>Встроенный веб-сервер (только для разработки). Пример: php -S localhost:8000 router.php.
-t <директория>Корневая директория для встроенного сервера.
-aИнтерактивный режим (REPL). Требует readline.
-c <путь>Указать php.ini (файл или директорию).
-nЗапустить без php.ini.
-d <ключ=значение>Установить директиву конфигурации (например, -d memory_limit=512M).
-vВерсия PHP и сборки.
-mСписок загруженных модулей.
-iИнформация о конфигурации (phpinfo() в консоли).
-lПроверка синтаксиса (lint).
-wПоказать исходный код без комментариев и пробелов («stripped»).
-z <расширение>Загрузить Zend-расширение (zend_extension).

Примеры:

# Проверка синтаксиса
php -l script.php

# Запуск с переопределённой директивой
php -d display_errors=1 -d error_reporting=E_ALL script.php

# Встроенный сервер
php -S localhost:8080 -t public/

# Построчная обработка stdin
echo -e "1\n2\n3" | php -R 'echo $argn * 2 . "\n";'

15.1.2. Специфика CLI-SAPI

ОсобенностьЗначение
max_execution_time0 (бесконечно)
memory_limit-1 (без ограничений, если не переопределено)
register_argc_argvOn (доступны $argc, $argv)
html_errorsOff
implicit_flushOn
output_bufferingOff

⚠️ В CLI нет $_SERVER['REQUEST_METHOD'], $_GET, $_POST, $_COOKIE, $_SESSION (если не запущена явно).


15.2. FPM (FastCGI Process Manager)

15.2.1. Конфигурация пулов (/etc/php/8.x/fpm/pool.d/www.conf)

ДирективаПримерНазначение
listen/run/php/php8.3-fpm.sock или 127.0.0.1:9000Сокет/порт для приёма запросов.
listen.owner, listen.group, listen.modewww-data, www-data, 0660Права на Unix-сокет.
user, groupwww-dataОт чьего имени работают процессы.
pmdynamic, static, ondemandРежим управления процессами.
pm.max_children50Макс. число дочерних процессов.
pm.start_servers5Стартовое число (для dynamic).
pm.min_spare_servers, pm.max_spare_servers2, 10Мин./макс. «свободных» процессов.
pm.max_requests500Перезапуск процесса после N запросов (защита от утечек памяти).
request_terminate_timeout30sМакс. время выполнения запроса (аналог max_execution_time, но на уровне FPM).
rlimit_core, rlimit_files, rlimit_dataОграничения ресурсов (ulimit).

15.2.2. Передача переменных от веб-сервера

Nginx → FPM:

location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

Ключевые fastcgi_param:

  • QUERY_STRING
  • REQUEST_METHOD
  • CONTENT_TYPE
  • CONTENT_LENGTH
  • SCRIPT_NAME, REQUEST_URI, DOCUMENT_URI
  • DOCUMENT_ROOT
  • SERVER_PROTOCOL, HTTPS, REMOTE_ADDR, REMOTE_PORT
  • SERVER_SOFTWARE, GATEWAY_INTERFACE
  • REDIRECT_STATUS (для Apache совместимости)

15.3. Apache (mod_php, устаревшее)

Директива .htaccess / httpd.confПример
php_value memory_limit 256MУстановка memory_limit.
php_flag display_errors OffУстановка булевой директивы.
php_admin_value, php_admin_flagТо же, но не переопределяется через ini_set() (только в виртуальных хостах/сервере).

⚠️ mod_php загружает PHP в каждый процесс Apache (даже для статики) — неэффективно. Рекомендуется FPM + mod_proxy_fcgi.


Магические методы, магические константы, атрибуты

16.1. Магические методы

МетодСигнатураВерсияНазначение
__construct(...$args)Конструктор. Вызывается при new.
__destruct()Деструктор. Перед уничтожением объекта.
__call(string $name, array $arguments)Вызов несуществующего/недоступного метода.
__callStatic(string $name, array $arguments)5.3То же, для статических методов.
__get(string $name)Чтение несуществующего/недоступного свойства.
__set(string $name, mixed $value)Запись в несуществующее/недоступное свойство.
__isset(string $name)isset($obj->prop).
__unset(string $name)unset($obj->prop).
__sleep()Возвращает массив имён свойств для serialize(). Может содержать логику перед сериализацией.
__wakeup()Вызывается после unserialize().
__toString()Преобразование объекта в строку (например, echo $obj). Должен возвращать string.
__invoke(...$args)5.3Вызов объекта как функции: $obj().
__debugInfo()5.6Возвращает массив для var_dump()/print_r() (переопределяет вывод свойств).
__clone()Логика при клонировании (clone $obj). По умолчанию — поверхностное копирование.

16.2. Магические константы (resolve-time)

КонстантаЗначение
__LINE__Номер строки.
__FILE__Полный путь к файлу.
__DIR__Директория файла (аналог dirname(__FILE__)).
__FUNCTION__Имя функции (без класса).
__CLASS__Имя класса (включая namespace).
__TRAIT__Имя трейта.
__METHOD__Имя метода (Class::method).
__NAMESPACE__Текущее пространство имён.

Значения определяются на этапе компиляции (раньше, чем opcache кэширует opcode).


16.3. Атрибуты (Attributes, PHP 8.0+)

16.3.1. Синтаксис и применение

#[Attribute(Attribute::TARGET_CLASS \| Attribute::TARGET_METHOD)]
class Route {
public function __construct(
public string $path,
public string $method = 'GET'
) {}
}

#[Route('/api/users', 'POST')]
class UserController {
#[Route('/{id}', 'GET')]
public function get(int $id): array { /* ... */ }
}

16.3.2. Флаги Attribute::TARGET_*

ФлагЗначение
TARGET_CLASSКласс
TARGET_FUNCTIONФункция
TARGET_METHODМетод
TARGET_PROPERTYСвойство
TARGET_CLASS_CONSTANTКонстанта класса
TARGET_PARAMETERПараметр метода/функции
TARGET_ALLЛюбое место (TARGET_CLASS | TARGET_FUNCTION | ...)

16.3.3. Чтение атрибутов через Reflection

$rc = new ReflectionClass(UserController::class);
$routeAttr = $rc->getAttributes(Route::class)[0] ?? null;
if ($routeAttr) {
$route = $routeAttr->newInstance(); // Route('/api/users', 'POST')
}

Константы расширений, HTTP-статусы, MIME-типы

17.1. HTTP-коды состояния (стандартные)

КлассПримерыPHP-константы (http_response_code(...))
1xx (информация)100 Continue, 101 Switching Protocols
2xx (успех)200 OK, 201 Created, 204 No Content, 206 Partial Content200, 201, 204, 206
3xx (перенаправление)301 Moved Permanently, 302 Found, 304 Not Modified, 307 Temporary Redirect, 308 Permanent Redirect301, 302, 304, 307, 308
4xx (ошибка клиента)400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 410 Gone, 429 Too Many Requests400, 401, 403, 404, 405, 410, 429
5xx (ошибка сервера)500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout500, 502, 503, 504

Установка: http_response_code(404); или header('HTTP/1.1 404 Not Found');.


17.2. MIME-типы (Content-Type)

ТипПримеры
text/*text/plain, text/html, text/css, text/csv, text/xml
application/*application/json, application/xml, application/pdf, application/zip, application/octet-stream
image/*image/jpeg, image/png, image/gif, image/svg+xml, image/webp
audio/*, video/*audio/mpeg, video/mp4
multipart/*multipart/form-data, multipart/byteranges

Установка:

header('Content-Type: application/json; charset=utf-8');

17.3. Константы расширений (выборочно)

17.3.1. json_*

  • JSON_ERROR_NONE, JSON_ERROR_DEPTH, JSON_ERROR_STATE_MISMATCH, JSON_ERROR_CTRL_CHAR, JSON_ERROR_SYNTAX, JSON_ERROR_UTF8, JSON_ERROR_RECURSION, JSON_ERROR_INF_OR_NAN, JSON_ERROR_INVALID_PROPERTY_NAME
  • JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT, JSON_FORCE_OBJECT, JSON_NUMERIC_CHECK, JSON_BIGINT_AS_STRING, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, JSON_PRESERVE_ZERO_FRACTION, JSON_INVALID_UTF8_IGNORE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_THROW_ON_ERROR

17.3.2. filter_*

  • FILTER_VALIDATE_INT, _BOOLEAN, _FLOAT, _REGEXP, _URL, _EMAIL, _IP, _MAC
  • FILTER_SANITIZE_STRING (устарело), FILTER_SANITIZE_EMAIL, FILTER_SANITIZE_URL, FILTER_SANITIZE_NUMBER_INT, FILTER_SANITIZE_NUMBER_FLOAT
  • FILTER_FLAG_ALLOW_OCTAL, FILTER_FLAG_ALLOW_HEX, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP, FILTER_FLAG_NO_ENCODE_QUOTES

17.3.3. date_*

  • DATE_ATOM, DATE_COOKIE, DATE_ISO8601, DATE_RFC822, DATE_RFC850, DATE_RFC1036, DATE_RFC1123, DATE_RFC2822, DATE_RFC3339, DATE_RSS, DATE_W3C
  • DateTime::ATOM, DateTime::COOKIE, ... (эквиваленты)

17.3.4. stream_*

  • STREAM_CLIENT_CONNECT, STREAM_CLIENT_ASYNC_CONNECT, STREAM_CLIENT_PERSISTENT
  • STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT, _TLSv1_1_CLIENT, _TLSv1_2_CLIENT, _TLSv1_3_CLIENT, и серверные аналоги

17.3.5. openssl_*

  • OPENSSL_ALGO_SHA1, SHA256, SHA512, MD5, RIPEMD160
  • OPENSSL_KEYTYPE_RSA, DSA, DH, EC

Практические шаблоны: Router, DI-контейнер, Middleware

18.1. Простой роутер (без зависимостей)

class Router
{
private array $routes = [];

public function add(string $method, string $pattern, callable $handler): void
{
$this->routes[] = [$method, $pattern, $handler];
}

public function dispatch(string $method, string $uri): void
{
foreach ($this->routes as [$m, $pattern, $handler]) {
if ($m !== $method) continue;

$pattern = preg_quote($pattern, '#');
$pattern = preg_replace('#\{(\w+)\}#', '(?P<$1>[^/]+)', $pattern);
$pattern = '#^' . $pattern . '$#u';

if (preg_match($pattern, $uri, $matches)) {
$params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
$handler($params);
return;
}
}
http_response_code(404);
echo "Not found";
}
}

// Использование
$router = new Router();
$router->add('GET', '/users/{id}', function ($params) {
echo "User ID: " . htmlspecialchars($params['id']);
});
$router->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));

18.2. Простой DI-контейнер (PSR-11-like)

interface ContainerInterface {
public function get(string $id);
public function has(string $id): bool;
}

class Container implements ContainerInterface
{
private array $definitions = [];
private array $instances = [];

public function set(string $id, callable $factory): void
{
$this->definitions[$id] = $factory;
}

public function get(string $id)
{
if (isset($this->instances[$id])) {
return $this->instances[$id];
}
if (!isset($this->definitions[$id])) {
throw new Exception("Entry '$id' not found");
}
return $this->instances[$id] = ($this->definitions[$id])($this);
}

public function has(string $id): bool
{
return isset($this->definitions[$id]);
}
}

// Использование
$container = new Container();
$container->set('pdo', fn() => new PDO('sqlite::memory:'));
$container->set('userRepository', fn($c) => new UserRepository($c->get('pdo')));

$userRepo = $container->get('userRepository');

18.3. Middleware (PSR-15)

interface RequestHandlerInterface {
public function handle(ServerRequestInterface $request): ResponseInterface;
}

interface MiddlewareInterface {
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
}

class LoggingMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$start = microtime(true);
$response = $handler->handle($request);
$duration = microtime(true) - $start;
error_log("{$request->getMethod()} {$request->getUri()->getPath()} — {$duration}s");
return $response;
}
}

class Dispatcher
{
public function dispatch(array $middlewareStack, ServerRequestInterface $request): ResponseInterface
{
$next = new class($middlewareStack) implements RequestHandlerInterface {
private int $index = 0;

public function __construct(private array $stack) {}

public function handle(ServerRequestInterface $request): ResponseInterface
{
if ($this->index >= count($this->stack)) {
return new Response(200); // default
}
$middleware = $this->stack[$this->index++];
return $middleware->process($request, $this);
}
};

return $next->handle($request);
}
}