Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Middle: питання на співбесіді з теми «Composer і PSR»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

4 питання

PSR-4 зіставляє префікс простору імен з каталогом. Решта імені класу перетворюється на шлях до файлу:

"autoload": {
    "psr-4": {
        "App\\": "app/"
    }
}

App\Services\Billing\Invoice → app/Services/Billing/Invoice.php.

Як це працює: vendor/autoload.php реєструє функцію через spl_autoload_register(). Коли код уперше звертається до невідомого класу, PHP викликає її, вона обчислює шлях і робить require. Класи, які не знадобилися в запиті, не завантажуються взагалі.

Що треба знати:

  • Регістр важливий: на Linux invoice.php для класу Invoice не знайдеться, хоча на macOS усе працюватиме. Класична причина «на проді клас не знайдено».
  • Один клас - один файл, ім'я файлу збігається з ім'ям класу.
  • Після зміни секції autoload у composer.json потрібен composer dump-autoload. Нові класи в уже налаштованому каталозі підхоплюються без нього.
  • Для файлів з функціями (не класами) є секція "files" - вони підключаються на кожному запиті.

Докладніше в документації: PSR-4 у composer.json

Обидва дозволяють оновлення, які за семантичним версіонуванням не мають ламати сумісність:

  • ^1.2.3 - від 1.2.3 до (не включно) 2.0.0. Дозволені всі мінорні й патч-оновлення.
  • ~1.2.3 - від 1.2.3 до (не включно) 1.3.0. Дозволені лише патчі.
  • ~1.2 - від 1.2 до 2.0. Остання вказана цифра може рости.

Нюанс з нулем: для версій 0.x мінорна версія вважається ламкою. ^0.3.1 - це від 0.3.1 до 0.4.0, а не до 1.0.

Що обирати:

  • ^ - стандарт для більшості залежностей. Саме його пише composer require.
  • Точна версія (1.2.3) - лише коли пакет відомий тим, що ламає сумісність у мінорних версіях, і оновлювати його хочеться тільки вручну.
  • * чи dev-master у застосунку - ні: сьогоднішній composer update може принести будь-що.

Важливо: обмеження в composer.json визначають, що дозволено. Що встановлено - записано в composer.lock, і на сервер їде саме воно.

Докладніше в документації: Версії й обмеження

За замовчуванням Composer шукає пакети на Packagist. Інші джерела додають у секцію repositories.

Git-репозиторій (приватний пакет):

"repositories": [
    { "type": "vcs", "url": "git@github.com:acme/billing-sdk.git" }
],
"require": {
    "acme/billing-sdk": "^2.1"
}

Composer читає теги репозиторію як версії. Доступ - через SSH-ключ або токен у auth.json (composer config --global github-oauth.github.com <token>), а в CI - через змінну COMPOSER_AUTH.

Локальна папка (розробка пакета поруч із застосунком):

"repositories": [
    { "type": "path", "url": "../packages/billing-sdk", "options": { "symlink": true } }
]

Зміни в пакеті одразу видно в застосунку, без публікації нових версій. Для монорепозиторіїв - "url": "packages/*".

Приватний реєстр: для кількох пакетів і великої команди зручніше Private Packagist, Satis (статичний реєстр) або реєстр пакетів GitLab/GitHub - ними керують як Packagist, з версіями й правами доступу.

Що варто знати:

  • Порядок важливий: репозиторії з repositories перевіряються перед Packagist. Пакет з тією ж назвою з вашого репозиторію матиме пріоритет - цим користуються для тимчасових форків з виправленням ("type": "vcs" на свій форк і версія dev-fix-branch).
  • Форк - тимчасовий захід. Виправлення варто віддати в оригінальний пакет і повернутися на нього, інакше ви самі підтримуєте форк.
  • path-репозиторій на проді зазвичай не використовують: локальний шлях там може не існувати.

Докладніше в документації: Репозиторії Composer

PER Coding Style - стандарт форматування PHP-коду від PHP-FIG, наступник PSR-12 (а той - PSR-2). Описує відступи (4 пробіли), розташування дужок, пробіли навколо операторів, порядок use, оформлення сигнатур, нові конструкції мови (enum, match, атрибути, property hooks).

Навіщо єдиний стиль: код-рев'ю обговорює суть, а не пробіли; diff-и не засмічуються переформатуванням; новий розробник читає код без звикання до особистих звичок кожного автора.

Інструменти, що форматують автоматично:

  • Laravel Pint - обгортка над PHP-CS-Fixer з пресетом Laravel (є й пресет per). У Laravel-проєктах - стандарт.
vendor/bin/pint            # виправити
vendor/bin/pint --test     # лише перевірити (для CI)
vendor/bin/pint --dirty    # лише змінені файли
  • PHP-CS-Fixer - гнучке налаштування правил.
  • PHP_CodeSniffer (phpcs/phpcbf) - перевірка й виправлення за стандартами.

Як впровадити, щоб працювало:

  1. Один конфіг у репозиторії (pint.json) - а не налаштування в IDE кожного розробника.
  2. Перевірка в CI - злиття неможливе, якщо стиль порушено.
  3. Автоформатування при збереженні в IDE чи pre-commit хук - щоб CI рідко падав.
  4. Одноразове переформатування всього коду окремим комітом, а його хеш - у .git-blame-ignore-revs, щоб git blame не показував цей коміт як автора кожного рядка.

Форматування ≠ якість коду: стиль ловить пробіли й дужки, а помилки логіки й типів - статичний аналіз (PHPStan/Larastan) і тести.

Докладніше в документації: PER Coding Style