Forge
markdowne8ad0934
1# PHP — данные и персистентность (PDO и обход без ORM)
2
3**Назначение:** фундамент **работы с БД из PHP** без привязки к Laravel/Eloquent: PDO, подготовленные запросы, транзакции, типичные ошибки. Мир **`software.php`**.
4
5---
6
7### 1. Почему PDO как дефолт
8
9- **Fact:** **PDO** — унифицированный слой с драйверами (`mysql`, `pgsql`, `sqlite`, …); единый стиль prepared statements; исключения в режиме `ERRMODE_EXCEPTION`.
10- **Heuristic:** новый код без тяжёлого ORM — PDO + тонкий репозиторий; mysqli допустим, но два API в одном проекте — только с обоснованием.
11
12---
13
14### 2. Подключение и DSN
15
16- **Fact:** DSN строка зависит от драйвера; учётные данные не хардкодить — env/config вне VCS.
17- **Heuristic:** для MySQL 8 — явно charset `utf8mb4` в DSN; timezone — задавать на соединении или в сервере согласованно.
18
19---
20
21### 3. Подготовленные запросы и плейсхолдеры
22
23- **Fact:** именованные и позиционные плейсхолдеры; для `IN (...)` — собирать плейсхолдеры динамически или использовать альтернативы (временные таблицы) — не конкатенировать сырые значения.
24- **Heuristic:** никогда не интерполировать пользовательские данные в SQL; идентификаторы таблиц/колонок — allowlist, не параметры prepared statement.
25
26---
27
28### 4. Эмуляция prepared statements
29
30- **Fact:** PDO может эмулировать prepares на клиенте (`ATTR_EMULATE_PREPARES`); для MySQL влияет на повторное использование планов и экранирование.
31- **Heuristic:** для прод-MySQL часто отключают эмуляцию (`false`), если нет причин иначе — проверить поведение лимитов/типов.
32
33---
34
35### 5. Транзакции и изоляция
36
37- **Fact:** `beginTransaction` / `commit` / `rollBack`; уровень изоляции задаётся SQL `SET TRANSACTION` (зависит от СУБД).
38- **Heuristic:** бизнес-операция «всё или ничего» — одна транзакция на use-case; не держать транзакции открытыми на время HTTP long poll.
39
40---
41
42### 6. Deadlock и retry
43
44- **Fact:** при deadlock СУБД откатывает одну транзакцию — приложение должно уметь **retry** идемпотентной операции.
45- **Heuristic:** логировать код ошибки; ограничить число повторов с backoff.
46
47---
48
49### 7. Потоковое чтение и память
50
51- **Fact:** `fetch` в цикле vs `fetchAll` — последний раздувает память на больших выборках.
52- **Heuristic:** отчёты и миграции данных — итерация с лимитом/ключом или курсоры (если поддерживаются).
53
54---
55
56### 8. N+1 на уровне ручных запросов
57
58- **Fact:** без ORM N+1 всё равно возможен: цикл по списку ID с запросом внутри.
59- **Heuristic:** собрать ID → один запрос `WHERE id IN (...)` + карта в памяти; или JOIN с осознанием дублирования строк.
60
61---
62
63### 9. Миграции схемы без фреймворка
64
65- **Fact:** инструменты: **Phinx**, **Doctrine Migrations**, самописные SQL с таблицей версий.
66- **Heuristic:** миграции идемпотентны в рамках версии; никогда не править уже применённую миграцию в истории — новая миграция.
67
68---
69
70### 10. SQLite и продакшен
71
72- **Fact:** SQLite удобен для тестов/edge; в высоконагруженном concurrent write — ограничения.
73- **Heuristic:** явно документировать, если прод на SQLite; иначе считать dev-only по умолчанию для web-scale записи.
74
75---
76
77## Registry card (template-knowledge-card-v1)
78
79### Provenance
80- source_refs: `https://www.php.net/manual/en/book.pdo.php`; KB 2026-03-01.
81- created_at: 2026-03-01
82- updated_at: 2026-03-01
83
84### Metadata
85- card_id: KC-2026-03-01-PHP-DB-L1
86- world: software.php
87- layer: world
88- tags: php; pdo; sql; transactions; migrations
89- status: active
90
91### Epistemic Linkage
92- epistemic_basis: fact + inference
93- confidence: high
94- transfer_boundary: тюнинг конкретной СУБД — вендорная документация
95
96### Core Unit
97- context: сырой SQL из PHP, легаси скрипты, микросервис без ORM
98- signal: SQL injection, утечки соединений, deadlock
99- action: prepared statements + транзакции + профилирование запросов
100- lesson: PDO не отменяет дисциплину SQL
101
102### Operationalization
103- first_adoption_task: ERRMODE_EXCEPTION + единый слой репозитория
104- validation_check: статический поиск конкатенации в SQL
105- success_criterion: нет сырого пользовательского ввода в SQL
106
107### Lifecycle
108- supersedes: —
109- superseded_by: —
110- deprecation_reason: —
111
View only · write via MCP/CIDE