Данная статья рассчитана на тех, кто до этого ни разу не делал пакетов — проектов на голом PHP для своих нужд.
Хочу поделиться с вами своим опытом, с которым столкнулся, и предоставить шаблон, который написал для пакетов/проектов:
https://github.com/deniskorbakov/skeleton-php-docker
Буду очень рад звёздочке на GitHub и обратной связи после прочтения статьи!
Предыстория
В прошлой статье я рассказал про шаблон, который создал для хакатона — чтобы можно было стартовать с заготовками и не тратить время на настройку, а также переиспользовать его в своих проектах.
Недавно у меня возникла потребность в написании пакета. До этого я этим не занимался, поэтому начал исследовать тему: изучил информацию на Хабре и других форумах о том, как оформлять Composer и базово описывать пакет.
Как строиться проект
Структура проекта
Классическое построение проектов написанных на php
Пример
├── src # Директория вашего пакета
└── Dir1 # Директория для внутрений логики
│ └── PackageClass.php # Класс для внешнего использования
├── tests # Директория для тестов
│ ├─ Fixtures
│ ├─ Unit
Этого формата придерживаются практически во всех проектах — это ключевые директории. Однако вы можете создавать дополнительные папки, чтобы выносить логику отдельных частей приложения в свои слои.
Названия папок могут быть любыми, но лучше следовать общепринятым практикам, чтобы другим разработчикам было проще ориентироваться в вашем коде.
Пример возможных директорий:
scripts/
— скрипты для сборки, деплоя или других задач.assets/
— статические файлы (стили, скрипты, изображения)..docker/
— конфигурация Docker (Dockerfile, Docker Compose).public/
— точка входа для веб-сервера (если пакет включает веб-интерфейс).config/
— файлы конфигурации приложения.
Composer
Базовая структура composer
Подробнее о настройке можно прочитать здесь.
Ключевые параметры при создании пакета:
name/description/keywords:
Пример
"name": "deniskorbakov/skeleton-php-docker",
"description": "A skeleton php libs with docker",
"keywords": ["php", "skeleton", "package", "docker"],
name
— имя пакета в форматеvendor/package
.description
— краткое описание функциональности.keywords
— теги для поиска в Packagist.
require:
Пример
"require": {
"php": ">=8.2"
},
Указывает минимальную версию PHP и зависимости, без которых пакет не работает.
require-dev:
Пример
"require-dev": {
"pestphp/pest": "^3.8",
"phpstan/phpstan": "^2.1",
"rector/rector": "*",
"squizlabs/php_codesniffer": "^3.13",
"slevomat/coding-standard": "^8.20",
"orchestra/testbench": "^10.4"
},
Зависимости для разработки (тестирование, статический анализ).
autoload
Пример
"autoload": {
"psr-4": {
"DenisKorbakov\\SkeletonPhpDocker\\": "src/"
}
},
Настройка автозагрузку для вашего пакета.
Полезные команды и скрипты
Команды:
composer validate
— проверка корректностиcomposer.json
.composer outdated
— поиск устаревших зависимостей.
Пример скриптов:
Пример
"scripts": {
"tests": "pest --stop-on-failure --colors",
"tests-coverage": "pest --coverage --min=90",
"tests-mutation": "pest --mutate",
"lint": [
"@phpstan",
"@cs",
"@rector"
],
"phpstan": "phpstan analyse --memory-limit=2G",
"rector": "rector",
"cs": "phpcs"
},
Использование: composer tests
— запуск тестов.
Статические анализаторы и линтеры
Зачем они нужны
Каждый из нас хочет придерживаться хорошего качества от кода, но бесконечные ревью с указанием на одни и те же ошибки в форматировании могут раздражать людей между с собой и как минимум решением данной проблемы стали линтеры
Линтер — инструмент для автоматического анализа кода на соответствие стандартам оформления.
Статические анализаторы помогают находить ошибки до запуска кода, улучшая его надёжность.
Статический анализатор — инструмент, который проверяет код на ошибки, уязвимости и антипаттерны без его выполнения.
Внедрение этих инструментов в старые проекты может быть сложным, поэтому иногда разумно применять их только к изменённым файлам.
PHPstan
Один из самых популярных анализаторов для PHP. Его главное преимущество — уровни строгости (от 0 до 9). Чем выше уровень, тем тщательнее проверка.
Полезные плагины:
cognitive-complexity — оценивает сложность кода.
Сложность кода — метрика, показывающая, насколько код труден для понимания и поддержки.
PHP_CodeSniffer (PHPCS)
Проверяет код на соответствие стандартам (PSR-12, PSR-2). Можно настроить собственные правила.
Rector
Инструмент для автоматического рефакторинга. Например, может обновлять синтаксис с PHP 7.4 на 8.2.
Тестирование
Никогда нельзя доверять себя, а тем более своему коду
Тесты помогают убедиться, что код работает как ожидается.
Pest
Я выбрал Pest вместо PHPUnit из-за более лаконичного синтаксиса. Однако у него есть минус: подсветка синтаксиса работает только с официальным плагином.
Пример теста:
Пример
test('sum', function () {
expect(1 + 1)->toBe(2);
});
GitHub Actions
Автоматизация тестов и линтеров
Пример workflow для линтинга:
Пример
name: LINT
on: ['push']
jobs:
coding-standard:
name: Coding Standard
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP 8.4
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: none
- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: composer-${{ hashFiles('composer.lock') }}
- name: Install dependencies
run: composer install
- name: Run lint code
run: composer lint
Пример тестов:
Пример
name: TESTS
on: ['push']
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php:
- '8.4'
- '8.3'
- '8.2'
name: Tests (PHP ${{ matrix.php }} - ${{ matrix.deps }})
steps:
- uses: actions/checkout@v3
- name: Setup PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- name: Install dependencies
run: composer update
- name: Test code
run: composer tests
- name: Test coverage
run: composer tests-coverage
- name: Test coverage
run: composer tests-mutation
Шаблоны для issue
Так же очень хорошая практика делать шаблоны по которому клиенты вашего пакета - приложения смогу составить баг репорт или спросить про его работу
Так как в нем можно указывать инпуты которые они должны заполнить:
Версия пакета
Версия зависимости
Чекбокс для того чтобы подтвердить ознакомление с другими issue
Примеров может быть много но самое главное что не будет от вас ответов о том что пользователь предоставил вам нужную информацию чтобы ему помочь
Пример шаблона:
Пример
name: Bug report
description: |
Something didn't work as expected? Create a report to help us improve.
labels: [ "bug", "triage" ]
assignees: [ ]
body:
- type: markdown
attributes:
value: |
Example description
- type: input
id: pkg_version
attributes:
label: Package name version
description: Run `composer show -v | grep package/name`.
placeholder: "example: 1.0.0"
validations:
required: true
- type: input
id: php_version
attributes:
label: PHP version
description: Run `php -v`.
placeholder: "example: 8.4"
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: |
Example description
placeholder: I ran `php artisan migration:fresh` on prod, and then...
validations:
required: true
На выходе мы получим вот такую форму в issue:
Пример - фото

Релиз на pakagist
Описание процесса
Перейдите на Packagist.
Укажите ссылку на репозиторий.
Дождитесь модерации.
Пакет будет автоматически обновляться при пуше в main
. Для мгновенных обновлений используйте Packagist Update.
Пример - фото

Вывод
Я описал ключевые моменты создания пакета. Надеюсь, статья поможет тем, кто раньше не занимался этим.
Шаблон проекта - вы так же можете его улучшать отправив в него PR
GitHub - буду рад вашей подписки на меня и в гитхабе
Благодарю вас, что прочитали данную статью.