<? phpukraine СПІВБЕСІДИ
⌕Пошук по платформі

Питання на співбесіду Middle PHP

Рівень, де вже питають про N+1, транзакції, черги, тестування й уміння читати чужий код. Найбільша частина ринку.

Тема
Рівень
82 питання
ARC
Архітектура·Middle ·design patterns ·Adapter ·Facade

Адаптер підганяє один чужий обʼєкт під інтерфейс, якого вже чекає ваш код, і поведінки не змінює. Фасад вводить новий, простіший вхід до кількох сервісів підсистеми й сам знає порядок їх виклику. Фасади Laravel (`Cache::`, `Mail::`) - це статичні проксі до одного сервісу з контейнера, підсистеми за ними немає, тож з GoF Facade їх повʼязує лише назва.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·design patterns ·Strategy ·State

Структура в них однакова: контекст тримає обʼєкт за інтерфейсом і делегує йому роботу. Різниця в тому, хто і коли цей обʼєкт міняє: стратегію обирає клієнт або конфіг, і вона нічого не знає про інші, а стан обʼєкт перемикає сам після дії, і кожен стан знає, куди з нього можна перейти.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·types ·union ·intersection

PHP 8.0 дав union (`int|string`), `mixed` як верхній тип і `static` як тип повернення; 8.1 додав `never` і intersection (`A&B`); 8.2 дозволив DNF - комбінації виду `(A&B)|null`. Повернення в нащадку можна звужувати, параметри розширювати, типи властивостей мають лишатися незмінними.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·SQL injection ·Eloquent ·Query Builder

Query Builder передає через плейсхолдери лише значення: аргументи `where()`, `whereIn()`, `insert()`, `update()`. Усе, що ви пишете рядком у `DB::raw()`, `whereRaw()`, `selectRaw()`, `orderByRaw()`, `havingRaw()`, `DB::select()` чи `DB::statement()`, іде в SQL як є, тому дані туди передають лише масивом біндінгів. Імена колонок і напрям сортування не біндяться взагалі, для них потрібен перелік дозволених значень.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·flaky-тести ·Clock ·PSR-20

Flaky-тест то проходить, то падає на тому самому коді. Найчастіші причини: прихований час (`now()`, `new DateTimeImmutable()`), випадкові дані, залежність від порядку тестів і спільного стану, мережа й паралельність. Час роблять явною залежністю (порт Clock, PSR-20, `FrozenClock`) або зупиняють через `travelTo()`/`freezeTime()`, випадковість передають як `Random\Randomizer` з seed, а порядок перевіряють запуском з `--order-by=random`.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·репозиторій ·Eloquent ·Doctrine

Репозиторій виправданий, коли він виглядає як колекція агрегатів у мові домену й тримає доменний шар без Illuminate чи Doctrine; він шкодить, коли перетворюється на generic CRUD-обгортку, що повертає той самий Builder або модель і лише додає шар.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·PostgreSQL ·MySQL ·типи даних

PostgreSQL дає транзакційний DDL, багату систему типів (масиви, діапазони, справжні ENUM-типи), суворі правила GROUP BY і порівняння типів, RETURNING та екосистему розширень; MySQL фіксує кожен DDL негайно, мовчки приводить типи й порівнює рядки без урахування регістру.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·OOP ·static ·self

`self::` і `parent::` - посилання на клас, зафіксовані на етапі компіляції за місцем написання коду, а `static::` резолвиться в рантаймі в клас, на якому виклик почався. Це і є late static binding (PHP 5.3+): завдяки йому `new static()` у батьківській фабриці створює нащадка, а `static::CONST` бере константу нащадка.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·test doubles ·Mockery ·фейки

Підміняють те, що повільне, недетерміноване або має побічні ефекти: базу, мережу, пошту, час, випадковість. Value objects і доменні класи беруть справжні. Чужі бібліотеки не мокають напряму: їх загортають у власний вузький порт, домен тестують з фейком цього порту, а сам адаптер integration-тестом проти справжньої бібліотеки чи записаних відповідей.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·PHPStan ·static analysis ·baseline

Рівні 0-10 вмикають правила порціями: 0-3 ловлять неіснуючі символи й неузгоджені return-типи, 5 перевіряє типи аргументів, 6 вимагає типізації, 8 забороняє звертатися до методів на nullable, 9-10 закривають mixed. У легасі це вводять baseline: заморозити наявні помилки у phpstan-baseline.neon, поставити аналіз у CI на червоне для нового коду і піднімати рівень по одному.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·Messenger ·черги ·AsMessageHandler

Messenger розділяє три речі. Повідомлення тримає лише дані, логіка живе в обробнику з #[AsMessageHandler] і методом __invoke(), а транспорт описується DSN у конфігу. Де саме обробник виконається, вирішує секція routing: без маршруту він спрацює синхронно в тому ж запиті, з маршрутом на doctrine/amqp/redis його підхопить воркер messenger:consume, а в тестах той самий код ганяють через sync:// або in-memory://.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·php8 ·match ·enum

8.0 дав match, іменовані аргументи, promotion, union-типи і `?->`; 8.1 - enum, readonly, first-class callable, Fibers; 8.2 - readonly-класи і DNF-типи; 8.3 - типізовані константи класу і `#[\Override]`; 8.4 - property hooks, асиметричну видимість і `new Foo()->method()` без дужок. Спільна лінія цих релізів: більше типів у сигнатурах і менше способів зіпсувати стан обʼєкта ззовні.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·SOLID ·дизайн ·принципи

На практиці найчастіше працюють два принципи: єдина відповідальність тримає класи малими й зрозумілими, інверсія залежностей робить код тестованим; решта є наслідками, і сліпе дотримання всіх пʼяти породжує зайві абстракції.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·strict_types ·declare ·TypeError

`declare(strict_types=1)` — це директива рівня одного файлу, яка вимикає приведення скалярів для викликів, зроблених із цього файлу: без неї PHP у coercive-режимі намагається сконвертувати аргумент до оголошеного типу (з PHP 8.0 нечислові рядки — це `TypeError`, а числові з «хвостом» — `int` плюс `E_WARNING`), зі strict приймається лише точний тип, з єдиним винятком `int` → `float`.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·service provider ·deferred ·singleton

Провайдер - єдине штатне місце для збирання застосунку: `register()` кладе привʼязки в контейнер, `boot()` викликається вже після того, як зареєструвалися всі провайдери. `bind` дає новий обʼєкт на кожне розвʼязання, `singleton` тримає один на весь життєвий цикл контейнера, а `scoped` - той самий singleton, який Octane і черговий воркер скидають між запитами та задачами.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·IDOR ·BOLA ·авторизація

IDOR (insecure direct object reference) виникає, коли застосунок знаходить обʼєкт за ідентифікатором із запиту і не перевіряє, чи належить він поточному користувачу. `auth` відповідає лише на питання «хто ви», тому для кожного обʼєкта потрібна окрема перевірка: шукати через звʼязок власника (`$user->resumes()->findOrFail($id)`), через policy або через `scopeBindings()` для вкладених маршрутів. UUID ускладнює перебір, але доступ не перевіряє.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·TDD ·red green refactor ·outside-in

TDD це цикл з трьох кроків: написати маленький тест, що падає з очікуваної причини (red), найпростішим кодом зробити його зеленим (green), прибрати дублювання й покращити дизайн під захистом тестів (refactor). Головна користь у фідбеку на дизайн, покриття тут лише побічний ефект: код, який важко протестувати першим, зазвичай має забагато залежностей. Найкраще працює для доменної логіки з чіткими правилами, гірше для дослідницького коду й UI.

Завантажую відповідь…
Сторінка питання →
PHP
Що таке property hooks у PHP 8.4+? ЧАСТО ПИТАЮТЬ
Core PHP·Middle ·PHP 8.4 ·property hooks ·інваріанти

Це можливість оголосити get і set логіку прямо на властивості, без окремих методів і без магії __get/__set.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·value object ·immutability ·DDD

Value object — незмінний обʼєкт без ідентичності, який описується лише своїм значенням: він валідує себе в конструкторі, тому в системі не існує невалідного екземпляра, і порівнюється за вмістом, а не за посиланням.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·віконні функції ·ROW_NUMBER ·LAG

Віконна функція рахує агрегат або позицію по групі рядків (вікні), не згортаючи їх у один рядок: ROW_NUMBER і RANK дають нумерацію всередині PARTITION BY, LAG бере значення попереднього рядка, SUM() OVER (ORDER BY …) дає running total — усе це замінює корельовані підзапити й самоджойни одним проходом.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·Generator ·yield ·yield from

Генератор — це функція з `yield`, яка при виклику не виконує жодного рядка тіла, а повертає обʼєкт `Generator` (реалізує `Iterator`): значення обчислюються по одному на вимогу, тому пікова памʼять не залежить від обсягу даних; ціна — один-єдиний прохід без перемотки, без `count()` і без доступу за індексом.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·доменні події ·DDD ·integration events

Доменна подія - це зафіксований факт у минулому часі, названий мовою бізнесу (`OrderPaid`), який сутність записує в себе, а застосунковий шар публікує після коміту. Події фреймворку (`kernel.request`, `eloquent.updated`, `postPersist`) описують технічний життєвий цикл запиту чи рядка, а інтеграційна подія - це окремий публічний контракт для інших сервісів, з власною версійованою схемою, який виїжджає через outbox і доставляється at-least-once.

Завантажую відповідь…
Сторінка питання →
OPS
DevOps·Middle ·nginx ·PHP-FPM ·FastCGI

nginx сам PHP не виконує: він упаковує запит у FastCGI-записи й віддає їх у сокет пулу PHP-FPM, де вільний воркер виконує скрипт із `SCRIPT_FILENAME`. Маршрутизацію задає `try_files`, пропускну здатність - `pm` і `pm.max_children`, який вважають від реально вільної памʼяті, а видимість проблем дають `slowlog` і `request_terminate_timeout`.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·file upload ·mimes ·finfo

Розширення, імʼя і MIME-тип із запиту задає клієнт, тож тип файлу визначають за вмістом (`finfo`, правило `mimes` у Laravel), імʼя і розширення генерують самі, а файл кладуть поза публічною текою, де вебсервер не виконає PHP. Віддають файли через контролер з перевіркою доступу або з окремого домену, а розмір обмежують на рівні nginx, PHP і валідації.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·Pest ·тестування ·фабрики

У Laravel «unit» і «feature» — це не «клас проти роуту», а «без завантаженого застосунку проти з ним»: у стандартному `tests/Pest.php` `Tests\TestCase` підключається лише до теки `Feature`, тому в `Unit` немає ні контейнера, ні фасадів, ні бази. Логіку без Illuminate тестують швидкими unit-тестами, все інше — feature-тестами через HTTP-межу з фабриками для даних і фейками (`Queue`, `Mail`, `Http`, `Storage`) для зовнішніх меж; фейк доводить лише факт виклику, тому job чи mailable потребують власного тесту.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·автентифікація ·guards ·Sanctum

Guard відповідає на питання «як пізнати користувача в цьому запиті» (session, token, sanctum), provider - «де його взяти» (eloquent-модель або таблиця через `database`). Sanctum закриває обидва типові випадки: персональні токени в `personal_access_tokens` для мобільних і сторонніх скриптів та звичайну cookie-сесію для свого SPA на тому ж домені. Passport потрібен лише тоді, коли ви самі стаєте OAuth2-провайдером із клієнтами, екраном згоди й refresh-токенами, а готовий фронтенд для входу беруть зі стартових наборів Laravel 12 (React, Vue, Livewire), бо Breeze і Jetstream уже не той шлях, який радить документація.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·Gate ·Policy ·авторизація

Усі чотири механізми - це один `Gate`: `Gate::authorize()` шукає policy за першим аргументом (`App\Models\Post` -> `App\Policies\PostPolicy`), інакше падає на іменовану здібність з `Gate::define()`, а `can` middleware, `$this->authorize()`, `authorize()` у Form Request і `@can` у Blade лише викликають його в різних точках запиту. Відмова кидає `AuthorizationException` -> 403, а `Response::denyAsNotFound()` перетворює її на 404, коли сам факт існування запису розголошувати не можна.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·Security ·Voter ·IsGranted

Будь-яка перевірка проходить через `isGranted($attribute, $subject)`: AccessDecisionManager опитує всі voter'и й зводить їхні голоси стратегією (за замовчуванням affirmative). Ролі перевіряє RoleHierarchyVoter, який розгортає `role_hierarchy`, а права на конкретний обʼєкт — власний Voter, підключений атрибутом `#[IsGranted('EDIT', subject: 'post')]`.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·безпека ·nonce ·capabilities

Nonce (wp_nonce_field + check_admin_referer) захищає від CSRF, current_user_can з конкретною здатністю — від перевищення прав, esc_* на виводі — від XSS, $wpdb->prepare — від SQL-інʼєкції. Це чотири різні шари, і жоден не замінює інший.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·WooCommerce ·хуки ·шаблони

Шаблони перевизначають копією у `wp-content/themes/{тема}/woocommerce/` зі збереженням шляху й контролем `@version`, логіку чіпляють на хуки WooCommerce, а дані пишуть через CRUD (`$product->update_meta_data()`, `$order->update_meta_data()`), бо при HPOS замовлення більше не живуть у `wp_posts`. Класичний і блоковий checkout мають різні точки розширення.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·Queue ·Horizon ·retries

Кількість спроб задають `$tries` (або `$maxExceptions`), паузу між ними — `$backoff` чи метод `backoff()`, дедлайн — `retryUntil()`, а фінальний обробник — `failed(Throwable $e)`. Ключова пастка не в цих властивостях, а в тому, що `retry_after` у config/queue.php має бути більшим за `$timeout` job, інакше воркер підхопить ще працюючий job і виконає його вдруге. Horizon дає ті самі налаштування на рівні супервізора, дашборд і теги; `ShouldBeUnique`, `Bus::batch()` і `Bus::chain()` керують не повторами, а тим, що взагалі потрапить у чергу і в якому порядку.

Завантажую відповідь…
Сторінка питання →
OPS
DevOps·Middle ·Docker ·шари образу ·multi-stage

Multi-stage: у білдерах Composer і збірка ассетів, у фінальному образі лише runtime, vendor без dev-залежностей і код; шари впорядковані так, щоб зміна коду не інвалідувала шар із залежностями.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·middleware ·Pipeline ·bootstrap/app.php

Middleware — це шари Pipeline навколо контролера: код до `$next($request)` бачить запит, код після — уже готову відповідь. Спершу йдуть глобальні (у порядку реєстрації, ще до роутера), потім групові й маршрутні — але ці фреймворк переставляє за списком пріоритетів, а `terminate()` викликається окремо, вже після відправки відповіді.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·DI ·compiler passes ·autowiring

Контейнер компілюється в PHP-клас на етапі cache warmup: autowiring читає типи в конструкторах, compiler passes змінюють визначення сервісів, а результат — статичний код без рефлексії в рантаймі.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·CPT ·таксономії ·wp_postmeta

CPT — це рядок у wp_posts із власним post_type, таксономія — нормалізована багато-до-багатьох звʼязка через term_relationships; таксономія годиться для фільтрів і категоризації, meta — для атрибутів запису, а власна таблиця потрібна, коли даних мільйони або потрібні складні фільтри й свої індекси.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·міграції ·zero-downtime ·PostgreSQL

Таблиця `migrations` зберігає лише імена вже виконаних файлів, тому правка старої міграції на проді не виконується ніколи і дає розʼїзд схеми між середовищами: зміну оформлюють новим файлом. Без простою це три окремі кроки в різних релізах - nullable-колонка, бекфіл порціями поза міграцією, і аж потім NOT NULL через `CHECK ... NOT VALID` та індекс `->online()` у міграції з `$withinTransaction = false`.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·EXPLAIN ·план запиту

Дивіться на тип доступу до таблиці, оцінку рядків проти фактичної кількості і найдорожчі вузли плану; розбіжність оцінки й факту вказує на застарілу статистику.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·design patterns ·Strategy ·Decorator

Робочий набір у PHP невеликий: Strategy за інтерфейсом із вибором у фабриці, Decorator для наскрізних дрібниць типу кешу й логів, Observer для реакцій на зміну стану. Фреймворки вже зібрані з них (драйвери кешу і сесій, `#[AsDecorator]`, Eloquent-обсервери), а Singleton у PHP-застосунку реалізує контейнер через `singleton()` чи shared-сервіс, не сам клас.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·design patterns ·Chain of Responsibility ·Pipeline

Обидва патерни передають запит послідовністю обробників, але з різним наміром: у Chain of Responsibility запит обробляє перша ланка, яка за нього взялася, і далі він не йде, а в Pipeline працює кожен крок і передає свій результат наступному. Middleware в Laravel і Symfony Messenger поєднує обидва: зазвичай шар передає запит далі й може змінити відповідь на зворотному шляху, але будь-який шар може зупинити обробку, повернувши відповідь сам.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·design patterns ·Factory Method ·Builder

Factory Method відповідає на питання «який клас створити»: базовий код просить продукт у власного методу, а конкретний клас визначає підклас, як `createRedisDriver()` у нащадках `Illuminate\Support\Manager`. Builder відповідає на питання «як зібрати один складний обʼєкт»: кроки з назвами й перевірка всіх правил разом у `build()`. Model factories у Laravel з Factory Method мають спільну лише назву: за змістом це незмінний будівельник тестових даних.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·named arguments ·constructor promotion ·PHP 8.0

Named arguments (PHP 8.0) дозволяють передавати аргументи за іменем параметра й пропускати необовʼязкові, а constructor property promotion (PHP 8.0) оголошує властивість прямо в сигнатурі конструктора; ціна — імена параметрів стають частиною публічного API, а промотована властивість ініціалізується ще до тіла конструктора.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·API ·REST ·GraphQL

Стиль API вибирається за клієнтами і за тим, що ви готові втратити: REST дає безкоштовне HTTP-кешування й прозорі логи, але ліпить over-fetching і зайві раунд-трипи; GraphQL забирає вибірку полів у клієнта, натомість вимикає кеш на CDN і переносить N+1 та авторизацію в резолвери; RPC виграє у внутрішній комунікації зі строгим контрактом. Для одного власного фронтенду GraphQL зазвичай зайвий - дешевше sparse fieldsets, include і BFF-ендпоінт під екран.

Завантажую відповідь…
Сторінка питання →
OPS
DevOps·Middle ·.env ·секрети ·конфігурація

Конфігурація приходить у процес через змінні оточення й відрізняється по середовищах, код лишається однаковим; .env — це локальна зручність розробника, яку не комітять, а на продакшені значення дає pool php-fpm, оркестратор або менеджер секретів. У Laravel env() дозволений лише у файлах config/, бо після config:cache .env не завантажується взагалі.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·EventDispatcher ·kernel.exception ·priority

Слухач і підписник - це один і той самий механізм із різним місцем конфігурації: підписник оголошує події й пріоритети всередині класу, слухач отримує їх ззовні (атрибут, YAML), і це зручніше для чужих подій та для налаштувань, що змінюються без правки коду. У `kernel.exception` головне - пріоритет (нижче нуля, щоб не з'їсти логування), `setThrowable()` для перетворення доменного винятку на HTTP-виняток і памʼять про те, що `setResponse()` зупиняє поширення події.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·Eloquent ·обсервери ·події

Обсервер - це набір слухачів, підвішених до подій збереження конкретної моделі, тож він мовчить на будь-якій масовій операції через білдер і за замовчуванням виконується всередині транзакції, ще до коміту. Подія зі слухачем описує бізнес-факт, диспатчиться явно з одного місця й дочекається коміту, якщо реалізує `ShouldDispatchAfterCommit`.

Завантажую відповідь…
Сторінка питання →
YII
Yii·Middle ·Yii2 ·Yii3 ·DI

Yii3 переписали з нуля: кілька десятків незалежних пакетів `yiisoft/*` замість монолітного фреймворка, DI-контейнер і конструктори замість глобального `Yii::$app`, PSR-15 middleware замість фільтрів-поведінок, PSR-3/6/7/11/14/15/16/17/18 замість власних інтерфейсів. Частина пакетів давно стабільна й працює в будь-якому PHP-проєкті, але повного стека зі стабільним релізом станом на зараз немає, тому будувати плани продукту навколо очікування Yii3 не варто.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·match ·switch ·PHP 8.0

`match` (PHP 8.0+) — це вираз, який повертає значення й порівнює строго через `===` без провалювання між гілками, а якщо жодна умова не збіглася і немає `default` — кидає `UnhandledMatchError`; `switch` — оператор, який порівнює нежорстко через `==`, потребує `break` і при відсутності збігу мовчки нічого не робить.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·пагінація ·keyset ·OFFSET

OFFSET не вміє «стрибати»: база читає й відкидає всі пропущені рядки, тому час зростає лінійно з номером сторінки. Keyset (seek method) замість номера сторінки передає ключ останнього прочитаного рядка й читає рівно LIMIT записів за постійний час.

Завантажую відповідь…
Сторінка питання →
OPS
DevOps·Middle ·CI ·тести ·статичний аналіз

Встановлення залежностей з кешем, перевірка стилю, статичний аналіз, тести на реальній базі й збірка артефакту; швидкі кроки першими, щоб пайплайн падав рано.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·WP-CLI ·деплой ·search-replace

WP-CLI завантажує WordPress у CLI-процесі без HTTP, тому дає скриптований доступ до ядра, плагінів і бази: перенесення через search-replace з коректною обробкою serialize(), запуск WP-Cron із системного crontab і власні команди через WP_CLI::add_command з нормальними exit-кодами для CI.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·покриття коду ·мутаційне тестування ·Infection

Покриття рахує, які рядки виконались під час тестів, але не чи помітив би тест їхню зміну: тест без перевірок дає 100%. Мутаційне тестування вносить у код дрібні зміни (мутанти: `>=` на `>`, `+` на `-`, `true` на `false`) і проганяє тести; мутант, на якому все зелене, вижив і показує неперевірене місце. У PHP це Infection і вбудований у Pest `--mutate`; частку вбитих мутантів показує MSI.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·CQRS ·команди ·запити

CQRS — це розділення операцій зміни стану (команди) і операцій читання (запити) на різні моделі: команди йдуть через доменні агрегати з інваріантами, читання — окремими DTO або навіть сирим SQL. Event sourcing і окрема база для читання — необовʼязкові додатки, а не частина визначення.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·CTE ·рекурсія ·PostgreSQL

CTE - це іменований набір рядків у межах одного запиту: WITH розкладає складну логіку на читабельні кроки, WITH RECURSIVE обходить ієрархію довільної глибини. З PostgreSQL 12 CTE з одним посиланням вбудовується в план, тож барʼєром оптимізації він більше не є за умовчанням.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·Fiber ·PHP 8.1 ·корутини

`Fiber` (PHP 8.1+) — це низькорівневий примітив кооперативної багатозадачності: блок коду з власним стеком, який можна призупинити з будь-якої глибини викликів через `Fiber::suspend()` і відновити через `resume()`. Планувальника й циклу подій у ядрі немає — їх дають revolt/event-loop та AMPHP v3.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·Doctrine ·Unit of Work ·flush

Doctrine відслідковує всі керовані обʼєкти й накопичує зміни в памʼяті; на flush() вона обчислює change set і виконує запити в правильному порядку.

Завантажую відповідь…
Сторінка питання →
YII
Yii·Middle ·Yii2 ·Behavior ·Event

Event — точка розширення в `yii\base\Component`: клас викликає `trigger()`, а зовнішній код підписується через `on()`. Behavior — обʼєкт, який прикріплюється до компонента в рантаймі, підписує свої методи на події через `events()` і додає компоненту власні властивості й методи через `__get`/`__call`. Разом вони дають повторне використання поведінки без успадкування.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·архітектурні тести ·Pest arch ·Deptrac

Архітектурний тест перевіряє будову коду, а не поведінку: хто кого імпортує, чи класи final, чи є strict_types, чи не лишився `dd()`. У Pest це `arch()->expect('App\Domain')->not->toUse('Illuminate')`: файли читаються парсером, код не виконується. Ними охороняють межі шарів і модулів, які інакше тихо зникають, а наявні порушення вносять у `ignoring()` явним списком.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·attributes ·reflection ·php8

Атрибути (PHP 8.0) - це структуровані метадані `#[Attr(...)]`, які компілятор зберігає разом із класом, методом, властивістю чи параметром і які читають через `getAttributes()` у Reflection. Сам атрибут нічого не робить: його треба знайти рефлексією і перетворити на обʼєкт через `newInstance()`, тому продакшн-код робить це один раз під час прогріву кешу, а не на кожен запит.

Завантажую відповідь…
Сторінка питання →
ARC
Архітектура·Middle ·гексагональна архітектура ·порти й адаптери ·dependency inversion

Порт - це інтерфейс, який оголошує саме ядро застосунку під свою потребу, адаптер - реалізація цього інтерфейсу в інфраструктурі поверх конкретної технології. Домен і Application залежать лише від портів, зв'язування адаптерів робить service provider у Laravel або services.yaml у Symfony, а в тестах ті самі порти закриваються in-memory адаптерами.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·session fixation ·session hijacking ·session_regenerate_id

Фіксація сесії: зловмисник заздалегідь підсовує жертві відомий йому id сесії, жертва входить, і якщо id після входу не змінився, зловмисник уже в акаунті. Тому при кожній зміні рівня доступу id регенерують: `session_regenerate_id(true)` у PHP, а в Laravel 13 це робить сам `Auth::login()` і `Auth::attempt()`. При виході сесію інвалідовують (`invalidate()` і `regenerateToken()`), а викрадення cookie ускладнюють прапорцями `Secure`, `HttpOnly`, `SameSite` і префіксом `__Host-`.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·password reset ·hash_equals ·timing attack

Токен скидання генерують криптостійким генератором (`random_bytes()`, `Str::random()`), у базі зберігають лише його хеш, дають короткий термін дії і видаляють після використання. Порівнюють секрети через `hash_equals()`, бо `===` зупиняється на першому відмінному байті. Відповідь форми однакова для відомого і невідомого email, а час відповіді вирівнюють, щоб не можна було перевірити, хто зареєстрований.

Завантажую відповідь…
Сторінка питання →
YII
Yii·Middle ·Yii2 ·DI ·Container

У Yii2 два різні реєстри: `Yii::$container` (DI-контейнер, резолвить конструктори через рефлексію і за замовчуванням віддає новий обʼєкт) і ServiceLocator застосунку з секції `components` (ліниві синглтони на запит, доступні як `Yii::$app->db`). Обидва створюють обʼєкти через `Yii::createObject()`, тому конфіг у Yii2 це масив із `class` плюс публічні властивості, а не набір closure-привʼязок, як у Laravel.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·API ·JsonResource ·пагінація

Модель серіалізується через `toArray()`, тож форма відповіді — це набір колонок таблиці плюс випадково завантажені звʼязки й `$appends`: нова колонка публікується сама, а `$hidden` захищає лише те, що ви згадали. `JsonResource` — це білий список полів у явному класі, де `whenLoaded()` прибирає ключ замість ліниво тягнути звʼязок, а `Resource::collection($paginator)` сам додає `links` і `meta`.

Завантажую відповідь…
Сторінка питання →
TST
Тестування·Middle ·фабрики ·фікстури ·test data builder

Кожен тест має сам створювати рівно ті дані, від яких залежить його перевірка, і показувати їх у тексті тесту. Для моделей це фабрики зі станами (`Vacancy::factory()->published()`), для доменних обʼєктів у unit-тестах builder або Object Mother з розумними значеннями за замовчуванням. Спільні фікстури на весь набір зручні лише для довідників, бо інакше тести неявно залежать від чужих даних і ламаються від кожної зміни.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·REST API ·register_rest_route ·permission_callback

register_rest_route на хуку rest_api_init: namespace/версія, methods, callback, обовʼязковий permission_callback з current_user_can і args зі sanitize_callback та validate_callback; помилки повертаються як WP_Error зі status.

Завантажую відповідь…
Сторінка питання →
SEC
Безпека·Middle ·brute force ·rate limiting ·RateLimiter

Перебір закривають обмеженням частоти: у Laravel це `RateLimiter::for()` з ключем, що поєднує email і IP, плюс `throttle` middleware, який віддає 429 з `Retry-After`. Ліміт тримається в спільному кеші (Redis), а `$request->ip()` має бути справжньою адресою клієнта, тобто `TrustProxies` налаштований. Від credential stuffing ліміти допомагають мало, тому додають перевірку злитих паролів, 2FA і моніторинг, а замість постійного блокування акаунта використовують тимчасові затримки.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·JSON ·jsonb ·GIN

У PostgreSQL зберігайте jsonb і індексуйте його GIN для пошуку по довільних ключах або B-tree на виразі `(data->>'key')` для конкретного поля; у MySQL індекс на JSON можливий лише через згенеровану колонку, функціональний індекс (8.0.13+) або multi-valued index (8.0.17+). Помилка — тримати в JSON поля, які є в кожному рядку і за якими фільтрують чи джойнять: там потрібні звичайні колонки з типом, NOT NULL і зовнішнім ключем.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·Cache ·Redis ·теги

Кеш стає застарілим з двох причин: ключ не враховує всього, від чого залежить результат, або інвалідація не спрацювала (масовий update без подій моделі, forget усередині ще не закомміченої транзакції). Лікується не меншим TTL, а тегами й обсерверами з `$afterCommit`, а одночасний промах гарячого ключа — `Cache::lock()` або `Cache::flexible()`.

Завантажую відповідь…
Сторінка питання →
OPS
DevOps·Middle ·логи ·моніторинг ·observability

Логи пишемо структурованим JSON у stdout одним рядком на подію й віддаємо збирачу, помилки дублюємо в Sentry, де вони групуються за fingerprint і мають реліз та контекст, а сигналом «щось не так» служать не логи, а метрики RED (rate, errors, duration) з алертами на симптоми, які бачить користувач.

Завантажую відповідь…
Сторінка питання →
SQL
SQL·Middle ·N+1 ·pg_stat_statements ·JOIN

З боку бази N+1 виглядає не як повільний запит, а як один нормалізований запит із величезним calls і мікроскопічним mean_exec_time; лікується збором ключів і другим запитом з IN або = ANY, а JOIN підходить лише там, де він не множить рядки.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·Gutenberg ·блоки ·block.json

Сучасний шлях — block.json і register_block_type з шляхом до директорії блоку: метадані, скрипти й стилі описуються декларативно, а PHP-рендер задається через render або render_callback.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·транзакції ·lockForUpdate ·deadlock

DB::transaction($callback, $attempts) обгортає замикання в транзакцію, відкочує її на будь-якому Throwable і повторює лише при deadlock чи lock wait timeout; lockForUpdate() потрібен там, де ви читаєте значення, щоб на його основі писати, і блокування тримається до COMMIT — тому має сенс тільки всередині транзакції.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·Forms ·Validator ·DTO

Форма — це двонаправлений маппер HTTP-даних на обʼєкт: submit прогонить дані через трансформери, покладе їх у модель і лише потім викличе Validator, який валідує обʼєкт, а не поля; в JSON-API цей шар зайвий, бо `handleRequest` читає `$request->request`, а не тіло запиту, і краще брати `#[MapRequestPayload]`.

Завантажую відповідь…
Сторінка питання →
LR
Laravel·Middle ·scheduler ·cron ·withoutOverlapping

Розклад живе в коді, а cron має один рядок `* * * * * php artisan schedule:run`: цей процес щохвилини порівнює cron-вираз кожної задачі з поточною хвилиною і запускає лише ті, що настали. Від дублів захищають два різні локи в кеші - `withoutOverlapping()` не дає задачі наздогнати саму себе на одному вузлі, `onOneServer()` віддає хвилину одному серверу з кластера, - а справжню гарантію дає ідемпотентність самої операції.

Завантажую відповідь…
Сторінка питання →
WP
WordPress·Middle ·продуктивність ·object cache ·WP_Query

Спершу профілювання через Query Monitor, потім persistent object cache у Redis, правильні аргументи WP_Query, індекси або власні таблиці замість meta_query і повне кешування сторінок на рівні nginx.

Завантажую відповідь…
Сторінка питання →
YII
Yii·Middle ·RBAC ·авторизація ·Yii 2

RBAC у Yii2 будується на ієрархії ролей і дозволів з правилами: ієрархія зберігається в БД або файлі, перевірка йде через Yii::$app->user->can(), а правила додають динамічні умови на кшталт авторства.

Завантажую відповідь…
Сторінка питання →
SF
Symfony·Middle ·Doctrine ·N+1 ·fetch join

Lazy-проксі та PersistentCollection довантажують дані окремим запитом на кожну сутність; лікується fetch join (`addSelect` приєднаної асоціації), а для пагінації — Doctrine Paginator, який ріже сутності, а не рядки.

Завантажую відповідь…
Сторінка питання →
YII
Yii·Middle ·Yii2 ·кешування ·TagDependency

У Yii2 чотири рівні: кеш даних через компонент `cache` (`get`/`set`/`getOrSet`), кеш фрагментів через `beginCache()`/`endCache()`, кеш сторінок фільтром `yii\filters\PageCache` і HTTP-кеш фільтром `yii\filters\HttpCache` з `Last-Modified`/`ETag`. Інвалідація - або за часом, або через обʼєкт `Dependency`: `DbDependency` перевіряє результат дешевого SQL, `TagDependency` позначає групу ключів застарілою через `TagDependency::invalidate()`.

Завантажую відповідь…
Сторінка питання →
PHP
Core PHP·Middle ·SPL ·IteratorAggregate ·Countable

Мінімум - `IteratorAggregate` (обхід у `foreach` через `getIterator()`), `Countable` (`count()`), `JsonSerializable` (контроль над `json_encode()`) і `Stringable` (типізація `string|Stringable`). `Iterator` пишуть вручну лише коли треба керувати станом обходу, а `ArrayAccess` дає синтаксис `$obj['key']`, який ламає типізацію і статичний аналіз.

Завантажую відповідь…
Сторінка питання →
Прогрес карток і тестів зберігається у профілі. Створити профіль·Увійти