Создаем свой пакет на PHP

от автора

Данная статья рассчитана на тех, кто до этого ни разу не делал пакетов — проектов на голом 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

Описание процесса

  1. Перейдите на Packagist.

  2. Укажите ссылку на репозиторий.

  3. Дождитесь модерации.

Пакет будет автоматически обновляться при пуше в main. Для мгновенных обновлений используйте Packagist Update.

Пример — фото

Вывод

Я описал ключевые моменты создания пакета. Надеюсь, статья поможет тем, кто раньше не занимался этим.

Шаблон проекта — вы так же можете его улучшать отправив в него PR
GitHub — буду рад вашей подписки на меня и в гитхабе

Благодарю вас, что прочитали данную статью.


ссылка на оригинал статьи https://habr.com/ru/articles/935544/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *