Forge
markdowne8ad0934
1# PHP 8.x — язык и семантика (фундаментальный проход)
2
3**Назначение:** целостная карта **семантики PHP 8.x** (ориентир **8.4+**): типы, объекты, ошибки, пространства имён, граничные случаи. Мир **`software.php`**. Хронология фич по мажорам с **5.x** — `kb-php-versions-and-evolution-v1.md`. Рантайм/SAPI/Composer — в `kb-php-fundamentals-v1.md`; веб-слой — в `kb-php-web-sessions-io-v1.md`.
4
5---
6
7### 1. Модель выполнения и единица компиляции
8
9- **Fact:** PHP компилирует скрипт в **opcode** и исполняет в рантайме Zend VM; `include`/`require` — отдельные компиляции при первом попадании (с учётом OPcache). Нет отдельного «линковера» как в C; порядок подключения файлов влияет на видимость классов/функций до автозагрузки.
10- **Heuristic:** полагаться на **PSR-4 + один entrypoint** вместо длинных цепочек `require`; для логики порядка инициализации использовать явный composer autoload и композицию, не «кто первый подключился».
11
12---
13
14### 2. Переменные, присваивание, ссылки
15
16- **Fact:** переменные — контейнеры zval; **присваивание** объектов — по handle (не глубокое копирование); **присваивание массивов** — копирование по значению (copy-on-write); оператор `&` создаёт **псевдоним**.
17- **Heuristic:** избегать `&` в публичных API; с `foreach ($arr as &$v)` сбрасывать ссылку `unset($v)` после цикла — иначе последующие присваивания ломают массив неочевидно.
18
19---
20
21### 3. Скаляры и `strict_types`
22
23- **Fact:** без `declare(strict_types=1)` внутри файла встроенные и пользовательские функции могут применять **слабые приведения** скаляров к объявленным типам; со `strict_types=1` несовместимые скаляры дают `TypeError`.
24- **Heuristic:** для новых модулей с контрактами — `strict_types=1`; граница HTTP/JSON (всё строки) — явно валидировать/кастовать до вызова строгого слоя.
25
26---
27
28### 4. Union, intersection, mixed, never, void
29
30- **Fact:** union (`string|int`), intersection только для классов (`A&B`), `mixed` — верх, `void` — только возврат «ничего», `never` — не возвращает (throw/exit/бесконечный цикл). Несовместимые union на рантайме → `TypeError`.
31- **Heuristic:** `mixed` не использовать как «не знаю» там, где можно перечислить union; `never` документирует завершение потока — полезно для статанализа.
32
33---
34
35### 5. Массивы как хеш-таблица
36
37- **Fact:** PHP-массив — упорядоченная хеш-таблица; ключи `int` и числовые строки приводятся по правилам индексации; отрицательные и большие int — валидны; `[]` — push.
38- **Heuristic:** для «словарей» не полагаться на неявное приведение строковых числовых ключей; для JSON-совместимости — нормализовать ключи перед `json_encode`.
39
40---
41
42### 6. Строки, кодировки, байты vs символы
43
44- **Fact:** строка PHP — **байтовая** последовательность; Unicode-семантика — через `mb_*` / `intl`; с 8.4 расширен mbstring (`mb_trim` и др.).
45- **Heuristic:** весь пользовательский текст — явная кодировка (UTF-8); не резать строки по байтам для UI — `mb_substr`; для бинарных данных — не проходить через «текстовые» фильтры.
46
47---
48
49### 7. Функции: сигнатуры, значения по умолчанию, variadic
50
51- **Fact:** параметры с default должны идти после обязательных; `...$rest` собирает остаток; именованные аргументы (8.0+) привязаны к имени параметра; порядок с именованными гибкий.
52- **Heuristic:** публичные функции — именованные аргументы только при стабильных именах параметров (рефакторинг ломает call sites).
53
54---
55
56### 8. Замыкания и стрелочные функции
57
58- **Fact:** замыкания — объекты `Closure`; захват `use ($x)` по значению или `&$x` по ссылке; короткие fn автозахватывают переменные по значению одним выражением.
59- **Heuristic:** не захватывать тяжёлые сервисы в fn без нужды; для долгоживущих очередей — сериализация closure ограничена — не хранить closures в сессии.
60
61---
62
63### 9. Классы, свойства, конструктор
64
65- **Fact:** свойства с типами проверяются при присваивании; **constructor property promotion** (8.0+) сокращает boilerplate; **readonly** (8.1+) — инициализация один раз (гибкость с clone ограничена).
66- **Heuristic:** DTO/Value objects — `readonly` + типы; мутабельные сущности — явный контракт изменения состояния.
67
68---
69
70### 10. Property hooks и asymmetric visibility (8.4)
71
72- **Fact:** **property hooks** позволяют встроить get/set без ручных методов; **asymmetric visibility** — разный доступ на чтение и запись у свойства.
73- **Heuristic:** при миграции легаси не смешивать «голые public поля» и hooks в одной иерархии без дисциплины; статанализаторы должны поддерживать 8.4.
74
75---
76
77### 11. Наследование, static, late static binding
78
79- **Fact:** одиночное наследование классов; `static::` разрешается в runtime по вызываемому классу (LSB); `self::` — лексический класс.
80- **Heuristic:** фабрики и шаблонный метод — `static` + LSB; не злоупотреблять `static` состоянием — усложняет тесты.
81
82---
83
84### 12. Трейты, разрешение конфликтов
85
86- **Fact:** трейты — горизонтальная композиция; конфликтующие методы — `insteadof`, алиасы `as`.
87- **Heuristic:** трейты для пересекающегося поведения, не как «мини-наследование» глубоких иерархий.
88
89---
90
91### 13. Интерфейсы, перечисления enum (8.1+)
92
93- **Fact:** интерфейсы описывают контракт; enum — закрытый набор кейсов с опциональными методами; backed enum несёт скаляр.
94- **Heuristic:** enum вместо «магических констант» для доменных состояний; сравнение кейсов — идентичность, не значение backed без явного доступа.
95
96---
97
98### 14. Атрибуты (8.0+)
99
100- **Fact:** `#[Attr]` метаданные доступны через Reflection; не влияют на рантайм сами по себе без кода, который их читает (фреймворки, тесты).
101- **Heuristic:** не дублировать одно и то же в docblock и атрибуте без политики «источник правды».
102
103---
104
105### 15. `match`, `switch`, nullsafe `?->`
106
107- **Fact:** `match` сравнивает строго (`===`), без fallthrough; `switch` — loose до указания; `?->` цепочка прерывается на первом null.
108- **Heuristic:** предпочитать `match` для перечислений и union-ветвлений; nullsafe не заменяет валидацию домена.
109
110---
111
112### 16. Иерархия ошибок: Throwable, Error, Exception
113
114- **Fact:** всё бросаемое реализует `Throwable`; **`Error`** и подтипы — инженерные ошибки (TypeError, ParseError и т.д.), обычно не ловят в бизнес-коде; **`Exception`** — предметные исключения; до PHP 7 многие фаталы были некatchable.
115- **Heuristic:** ловить `Throwable` только на верхней границе (логер); в домене — узкие `Exception`; `Error` — чинить код, не маскировать.
116
117---
118
119### 17. Генераторы, Iterator, ArrayIterator
120
121- **Fact:** `yield` создаёт генератор; ключи/значения и send/throw — полный протокол; память лучше, чем материализация больших массивов.
122- **Heuristic:** не смешивать генератор с повторным проходом без пересоздания; для JSON API больших списков — потоковая запись или чанки.
123
124---
125
126### 18. Fibers (8.1+) — концепт
127
128- **Fact:** Fiber — низкоуровневый примитив для приостановки/возобновления стека; удобные async-абстракции строят библиотеки (ReactPHP, Amp и т.д.), не ядро.
129- **Heuristic:** без библиотеки не строить production async вручную на Fibers; понимать, что большинство расширений и mysqli блокирующие.
130
131---
132
133### 19. Пространства имён, use, автозагрузка PSR-4
134
135- **Fact:** `namespace` изолирует символы; `use` — алиасы; Composer генерирует автозагрузчик по PSR-4 (путь ↔ namespace prefix).
136- **Heuristic:** один класс — один файл; имя класса = имя файла; не полагаться на относительные `include` внутри библиотек.
137
138---
139
140### 20. Сравнение, равенство, `==` vs `===`
141
142- **Fact:** `==` приводит типы по таблице приведений (исторически много ловушек); `===` без приведения.
143- **Heuristic:** почти везде `===`; для чисел из строк — явная нормализация `filter_var`, `(int)`, `bcmath` для денег.
144
145---
146
147### 21. Опасные и чувствительные конструкции
148
149- **Fact:** `eval`, `create_function` (удалена), `assert` с строкой (устарело), `extract`, `parse_str` без второго аргумента, `unserialize` на недоверенных данных — высокий риск (RCE, mass assignment, object injection).
150- **Heuristic:** запрет в стандарте кодирования; если `unserialize` неизбежен — `allowed_classes` и доверенный поток.
151
152---
153
154### 22. Деструкторы, порядок завершения
155
156- **Fact:** `__destruct` вызывается при уничтожении объекта; порядок при shutdown и циклических ссылках + GC — нетривиален.
157- **Heuristic:** не освобождать критичные внешние ресурсы только в деструкторе — использовать явный `close()`/`try-finally`.
158
159---
160
161## Registry card (template-knowledge-card-v1)
162
163### Provenance
164- source_refs: `https://www.php.net/manual/en/langref.php`; обобщение семантики 8.x; KB 2026-03-01.
165- created_at: 2026-03-01
166- updated_at: 2026-03-01
167
168### Metadata
169- card_id: KC-2026-03-01-PHP-LANG-L1
170- world: software.php
171- layer: world
172- tags: php; semantics; types; oop; errors; namespace
173- status: active
174
175### Epistemic Linkage
176- epistemic_basis: fact + inference
177- confidence: high для базовой семантики; medium для edge GC/destructor
178- falsification_trigger: расхождение с manual для заявленной версии PHP
179
180### Core Unit
181- context: проектирование API, отладка TypeError, рефакторинг легаси
182- signal: «почему не сравнивается», «почему упал деструктор», «strict_types ломает»
183- action: пройти соответствующий §; сверить версию; минимальный reproduce
184- lesson: PHP 8.x строже к типам; слабое равенство — ловушка
185
186### Operationalization
187- first_adoption_task: включить level статанализа на новом коде
188- validation_check: тесты граничных типов и сравнений
189- success_criterion: предсказуемое поведение на границах
190
191### Lifecycle
192- supersedes: —
193- superseded_by: —
194- deprecation_reason: —
195
View only · write via MCP/CIDE