Junior: питання на співбесіді з теми «Composer і PSR»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
4 питання
composer installставить рівно ті версії, що записані вcomposer.lock. Нічого не оновлює.composer updateшукає найновіші версії, дозволені обмеженнями зcomposer.json, ставить їх і переписуєcomposer.lock.
Звідси правило:
- На проді, в CI і після
git pull- лишеinstall. Так у всіх однакові версії, і те, що перевірили тести, саме те, що поїде на сервер. update- свідома дія розробника, щоб оновити залежності. Після неї ганяють тести і комітять новийcomposer.lock.
composer install --no-dev --optimize-autoloader # прод
composer update laravel/framework --with-dependencies # оновити один пакет
Пастка: composer update без аргументів оновлює все одразу. Якщо після нього щось зламалося, важко зрозуміти, який пакет винен. Краще оновлювати пакети поштучно чи невеликими групами.
Якщо composer.lock немає, install поводиться як update і створює його.
composer.json описує дозволені версії (^11.0 - будь-яка 11.x). composer.lock фіксує точні версії всіх пакетів, разом із залежностями залежностей, і хеші їхнього вмісту.
Для застосунку - комітити обов'язково. Інакше кожен composer install у колеги, в CI чи на сервері поставить «найновіше, що підходить», і версії поступово розійдуться. Баг «у мене працює» часто саме звідси.
Для бібліотеки (пакета, який ставлять інші) lock-файл зазвичай не комітять або він ні на що не впливає: застосунок, який ставить бібліотеку, однаково розв'язує версії сам, за своїм lock-файлом.
Що ще дає lock-файл:
composer installшвидший, бо не треба розв'язувати залежності.composer auditперевіряє на відомі вразливості саме встановлені версії.- Diff
composer.lockу pull request показує, що реально оновилося.
Конфлікти в lock-файлі при злитті гілок не правлять руками: беруть версію однієї гілки й заново виконують ту composer require чи update, яка була в іншій.
Докладніше в документації: composer.lock у системі контролю версій
require- залежності, без яких застосунок не працює: фреймворк, бібліотеки для бізнес-логіки, SDK.require-dev- потрібні лише розробникам і CI: тестовий фреймворк (Pest, PHPUnit), статичний аналіз (PHPStan, Larastan), форматування (Pint), Faker, налагоджувальні панелі.
composer require guzzlehttp/guzzle
composer require --dev pestphp/pest
На продакшені dev-залежності не ставлять:
composer install --no-dev --optimize-autoloader
Це:
- зменшує розмір застосунку й образу;
- прибирає з сервера інструменти, яких там не має бути (менше коду - менша поверхня атаки);
- пришвидшує автозавантаження.
Типова помилка: клас з dev-пакета використовується в робочому коді. Локально все працює, бо dev-пакети встановлено, а на проді - Class not found. Приклад - фабрики й Faker у сидерах, які запускають на проді, або налагоджувальний пакет, підключений у сервіс-провайдері без перевірки оточення.
Як ловити: CI-крок, що встановлює залежності з --no-dev і запускає застосунок (або хоча б php artisan чи тести, що не потребують dev-пакетів), а також composer-require-checker для перевірки, що весь код покритий оголошеними залежностями.
Для бібліотек require-dev ще важливіший: споживачі бібліотеки отримують лише її require, тож тестові інструменти бібліотеки до них не потрапляють.
Скрипти в composer.json - іменовані команди, які запускають через composer run (або коротко composer <назва>), і хуки на події Composer.
"scripts": {
"test": "pest --parallel",
"lint": ["pint --test", "phpstan analyse"],
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently \"php artisan serve\" \"php artisan queue:listen\" \"npm run dev\""
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
]
}
composer test
composer lint
composer dev
Навіщо:
- Єдині команди для команди й CI. Не треба пам'ятати прапорці кожного інструмента -
composer testоднаковий локально й у пайплайні. - Хуки на події:
post-install-cmd,post-update-cmd,post-autoload-dump,post-create-project-cmd. Laravel черезpost-autoload-dumpвиявляє пакети (package:discover), а черезpost-create-project-cmd- генеруєAPP_KEY.
Що варто знати:
@phpу скрипті використовує той самий PHP, яким запущено Composer;@composer- той самий Composer;@other-script- викликати інший скрипт.- Виконувані файли з
vendor/binдоступні в скриптах без повного шляху. - За замовчуванням скрипт обмежений 300 секундами; для довгих (dev-сервер) -
Composer\Config::disableProcessTimeout. composer install --no-scriptsвимикає хуки - корисно в Docker-збиранні, поки код застосунку ще не скопійовано.
Безпека: скрипти пакетів-залежностей Composer не виконує - лише скрипти кореневого composer.json. Плагіни ж пакетів потребують явного дозволу в allow-plugins.