# Ноябрь 2018 — тройное ревью и выпускной gate «Интеграционные проверки PHP» Статус: **принят в публикационный слой 31 июля 2026 года**. Пакет П10 сохраняет стабильные slug, дату и автора базового архива: - editorial-2018-11-practice-php-integration-tests; - editorial-2018-11-mechanism-php-integration-tests; - editorial-2018-11-field-php-integration-tests. Артефакты П10: - web/scripts/upgrade-2018-11.mjs; - web/public/assets/editorial/2018/php-integration-contract-2018.svg; - web/public/assets/editorial/2018/php-test-boundary-2018.svg; - web/public/assets/editorial/2018/php-false-green-trace-2018.svg; - этот файл. Сам скрипт П10 не меняет web/data/articles.json: публикационный слой подключает его отдельным registry только по slug. В общем checkout во время работы могли появляться параллельные артефакты других пакетов; они не входят в этот список и П10 их не редактирует. Дата ревью: 31 июля 2026 года. ## 1. Факты и техника — пройдено ### Карта утверждений и первичных источников | Утверждение | Первичный источник | Оговорка в материале | | --- | --- | --- | | PHPUnit 7 запускает классы, наследующие PHPUnit\Framework\TestCase, и тесты из файлов *Test.php | [Getting Started with PHPUnit 7](https://phpunit.de/getting-started/phpunit-7.html) | Пример помечен как PHP 7.2 / PHPUnit 7.5; версия закрепляется проектом, а не статьёй | | setUp() и tearDown() создают и очищают fixture вокруг теста | [PHPUnit 7.5 Fixtures](https://docs.phpunit.de/en/7.5/fixtures.html) | Статья не выдаёт fixture за изоляцию всей системы: отдельно названы вторые соединения и HTTP | | Mock/test double позволяет контролировать соседа класса, но не является доказательством SQL, PDO или сети | [PHPUnit 7.5 Test Doubles](https://docs.phpunit.de/en/7.5/test-doubles.html) | Unit- и integration-тесты отвечают на разные вопросы и оба остаются нужны | | PDO::beginTransaction() выключает autocommit; rollBack() откатывает изменения и возвращает его, но MySQL может сделать неявный commit для DDL | [PDO::beginTransaction](https://www.php.net/manual/en/pdo.begintransaction.php), [PDO::rollBack](https://www.php.net/manual/en/pdo.rollback.php) | Миграции и DDL не запускаются внутри транзакции теста; показан только путь данных | | getenv() читает конфигурацию, а curl_exec() и curl_getinfo() позволяют различить transport error и HTTP-статус | [getenv](https://www.php.net/manual/en/function.getenv.php), [curl_exec](https://www.php.net/manual/en/function.curl-exec.php), [curl_getinfo](https://www.php.net/manual/en/function.curl-getinfo.php) | Пример допускает только локальный учебный callback; внешние URL, production-секреты и результаты вызова не выдумываются | ### Технический проход - Во всех трёх ревизиях ровно один главный вопрос: контракт PDO-репозитория; граница unit/integration; фальшивая зелень в связке БД/HTTP/конфигурации. - Код вручную сверён с синтаксисом PHP 7.2: типы параметров и возврата, array(), методы PHPUnit 7; в тексте нет claim о запущенном контейнере, рабочем пароле или зелёном результате PHP-теста. - В коде HTTP учебный endpoint ограничен локальным адресом. Это не выдано за универсальную политику безопасности: для тестовой сети отдельно названы allowlist и отдельные credentials. - SQL, окружение, PDO и cURL не смешиваются в один диагноз. Каждой точке соответствует наблюдаемый факт и следующее действие. - DDL, второй PDO-коннект и HTTP не объявлены автоматически откатываемыми. Граница уборки показана явно. ## 2. Редактура и голос М1 — пройдено | Ревизия | Симптом и цена в первых двух абзацах | Один вопрос | Артефакт | Голос и ограничение | | --- | --- | --- | --- | --- | | Практика | Unit зелёный, но запись/чтение ломается; цена — неделя правок не той логики | Какой договор должен проверить PDO integration test | Тест INSERT → SELECT → rollback, таблица контракта, схема | Короткие шаги 2018 года; тестовая БД и контейнер не выдаются за запущенные | | Механизм | Mock зелёный, но SQL/конфигурация не работают; цена — ложная уверенность при рефакторинге | Где граница unit и integration | Соседние unit- и integration-примеры, таблица вопросов | Нет поздних SLO/observability-терминов; история ограничена PHP 7.2/PHPUnit 7.5 | | Поле | Регистрация 500 после записи или не уведомляет; цена — потеря следа и подмена реального клиента | Как увидеть разрыв БД/HTTP/config | Локальный callback, request ID, cURL-адаптер, трассировочная таблица | Учебная трасса не названа инцидентом; production endpoint запрещён | - М1 сохранён: текст идёт по формуле «симптом → причина → проверка → действие → результат → ограничение», использует короткие предметные абзацы и допускает «разберём», «сначала проверяем» только рядом с конкретным действием. - Не используются вводные о «современном мире», обещания универсального решения, SLO, Kubernetes, feature flags, продуктовые метрики или нераскрытый зрелый жаргон. - В каждой статье есть не менее пяти смысловых разделов, таблица с thead и scope, код, упорядоченный маршрут, один собственный SVG с содержательным alt/figcaption, ограничения и точный заголовок <h2>Проверяемые источники</h2>. ## 3. Визуал и выпуск — пройдено после локальных проверок - php-integration-contract-2018.svg объясняет узкий контракт PHPUnit → PDO → test DB → rollback; данные и DDL не показаны как часть одного обратимого действия. - php-test-boundary-2018.svg контрастно разделяет подменённый репозиторий в unit-тесте и настоящий PDO/cURL-адаптер в integration-тесте. Пунктир отмечает именно границу подмены. - php-false-green-trace-2018.svg показывает порядок config → PDO → cURL → 202 и нижний integration-маршрут с request ID; смысл не зависит только от цвета. - Все SVG имеют собственные title/desc, вертикальный viewBox 720 × 900, контрастный текст и без скриптов, внешних ресурсов или raster-вложений. ### Фактически выполненные команды и доказательства Выполнены следующие проверки: node --check web/scripts/upgrade-2018-11.mjs node web/scripts/upgrade-2018-11.mjs --print-revisions | node --input-type=module -e "import('./web/scripts/upgrade-2018-11.mjs').then(...)" xmllint --noout web/public/assets/editorial/2018/php-*-2018.svg Результаты: - node --check завершился с кодом 0. - Прямой --print-revisions выдал валидный JSON ровно с тремя slug: practice, mechanism и field П10. Import модуля не печатал побочных данных и вернул revisions.length === 3. - xmllint принял все три SVG. Проверка пяти файлов не нашла строк с хвостовыми пробелами. - Структурный аудит прошёл: практика — 8 753 знака основного тела и 7 541 знак без кода/источников; механизм — 9 044 и 7 578; поле — 10 956 и 7 900. У каждой ревизии 9 h2, одна схема, таблица, код, упорядоченный маршрут, два или более источника и явный симптом в первых 800 знаках. - SVG открыты через локальную статическую выдачу на viewport 375 × 812. Для каждого clientWidth === scrollWidth === 375; после переделки вертикальная компоновка сохранила читаемые подписи. DOM каждой схемы содержит SVG, но не содержит script или inline event handler. - В окружении нет PHP CLI: php --version вернул command not found. Поэтому PHP-фрагменты прошли фактологический и ручной синтаксический проход, но не выдаются за запущенные тесты. Для реального прогона нужны отдельные test-only DSN и локальный callback. После интеграции в registry строгий аудит опубликованного слоя прошёл для всех трёх slug. Он подтвердил сохранность date/author базового архива, диапазон 8 753 / 9 044 / 10 956 знаков тела, обязательные figure, таблицы, код, маршруты и источники. `npm run build` завершился с кодом 0 и сгенерировал 374 статические страницы. ## 4. Дополнительный выпускной проход — пройдено Независимый draft-gate выявил, что автономные ревизии не должны переопределять date и author: эти поля принадлежат базовому архиву и защищают хронологию и авторство публикации. Из всех трёх exported objects эти ключи удалены. Сохранены только поля ревизии: slug, title, categories, cover, excerpt, contentHtml и readingMinutes. Повторные результаты: - npm run audit:draft -- scripts/upgrade-2018-11.mjs завершился с кодом 0: 8 753 / 9 044 / 10 956 знаков тела и три PASS. - node --check scripts/upgrade-2018-11.mjs завершился с кодом 0. - xmllint --noout принял все три SVG. npm вывел только не блокирующие предупреждения о пользовательских настройках store-dir, cache-dir и public-hoist-pattern; сам draft-gate прошёл. ## 5. Выпусковой вердикт Пакет принят к публикации. У связанного файла ревизий нет права менять date или author; registry накладывает только редакционные поля по стабильному slug. PHP-примеры не выдаются за реально запущенные тесты: ограничение окружения и требование отдельного test-only DSN остаются явно зафиксированными выше.