Создаем библиотеку на php и публикуем на packagist

от автора

Прежде чем приступать к написанию кода, нам нужно решить, что именно такого полезного мы можем создать, какие функции будет выполнять библиотека. Довольно популярным является написание библиотек, упрощающих работу с тем или иным API. Зачастую API представляют из себя большой список различных методов, работающих не только через GET method http-протокола. И это доставляет сложность при работе с ним у программистов: нужно постоянно учитывать все нюансы обращения к методу, его ответа, а еще может присутствовать аутентификация при работе и тд.

Гораздо проще иметь готовый класс или группу классов, через которые можно легко объектно-ориентированно работать, не сильно заботясь обо всех этих нюансах, к тому же современные IDE умеют подсказывать и подсвечивать, когда у вас есть такой класс, а стороннего API они никак не знают и не подскажут. Поэтому написание библиотеки-прослойки между API и использующим его приложением так популярно.

Наша основная цель научиться создавать и публиковать lib для composer, а не реализация крутого и огромного решения, поэтому я выбрал API, которое уже имеет официальную php client library, но все же его вполне можно дополнить, и тем самым упростить использование. Я говорю о Почте от Google: Gmail API. Если перейти на официальную страницу настройки и использования этого API https://developers.google.com/gmail/api/quickstart/php, то мы увидим, что она предполагает все же некоторую подготовительную работу прежде, чем можно будет приступить к непосредственной работе с почтой.

Посмотрим на листинг в пункте «Step 2: Set up the sample», там мы видим подключение composer зависимостей, затем функцию getClient(), которая создает подключение к сервису почты, и только после нее идет пример кода работы с почтовыми лейблами. Как минимум эту функцию мы можем вынести за скобки нашего основного веб-приложения в библиотеку, которую сделать доступной для установки на любой проект, где понадобится работа с Gmail. Конечно, в реальном мире разработки создавать библиотеку только ради упрощения одной функции идея не самая лучшая, но мы учимся, к тому же вполне вероятно, что во время работы мы войдем во вкус и придумаем, что еще можно упростить, ускорить и вынести в библиотеку кроме этой функции настройки и подключения.

Создание библиотеки

Этот пример еще хорош и тем, что мы увидим далее, как настроить дополнительную зависимость нашего решения от сторонних библиотек. Что ж приступим, создаем директорию для будущего расширения и инициализируем composer проект:

mkdir gmail && cd gmail composer init

Composer предлагает нам ввести данные о создаваемом пакете:

Welcome to the Composer config generator    This command will guide you through creating your composer.json config.  Package name (<vendor>/<name>) [zhukmax/gmail]:  Description []: Package for easy using Gmail Api Author [ZhukMax <zhukmax@ya.ru>, n to skip]:  Minimum Stability []: dev Package Type (e.g. library, project, metapackage, composer-plugin) []: library License []: Apache-2.0  Define your dependencies.  Would you like to define your dependencies (require) interactively [yes]? no Would you like to define your dev dependencies (require-dev) interactively [yes]? no  {     "name": "zhukmax/gmail",     "description": "Package for easy using Gmail Api",     "type": "library",     "license": "Apache-2.0",     "authors": [         {             "name": "ZhukMax",             "email": "zhukmax@ya.ru"         }     ],     "minimum-stability": "dev",     "require": {} }  Do you confirm generation [yes]? Include the Composer autoloader with: require 'vendor/autoload.php';

Обратим внимание на название пакета (Package name), оно должно быть уникальным для того, чтобы можно было разместиться в packagist. Так же мы видим, что composer в квадратных скобках [ ] предлагает ответ на свой же вопрос, и если нас он устраивает, то просто нажимаем на клавишу Enter, иначе после двоеточия пишем свой вариант. Для лицензии проекта я выбрал Apache второй версии, открытую лицензию, отлично подходящую для opensource публикуемых программных решений, так же есть крайне популярные MIT и GNU GPL (https://ru.wikipedia.org/wiki/GNU_General_Public_License). В поле Description одним предложением описываем свою библиотеку, а в Author можно перечислить авторов, мой Composer уже знает меня, и поэтому подставил по умолчанию. На вопросы о зависимостях (dependencies) я пока что ответил отрицательно, мы поставим нужные зависимости позже, а также добавим кое-что вручную прям в файл composer.json, в котором и хранятся все настройки проекта.

В конце после вопроса «Do you confirm generation [yes]?» мы нажали Enter, и в корне проекта появился файл composer.json. Откроем его и пропишем зависимость от php, я выбрал версию не ниже 7.1, так как седьмая версия выпущена уже более пяти лет. Но если вы предполагаете, что вашей библиотекой будут пользоваться на проектах с php 5, тогда можно проставить «>=5.6.0». Далее запускаем команду установки зависимости от официальной Gmail API библиотеки:

composer require google/apiclient:^2.0

Это займет некоторое время, добавляем autoload, который позволит Composer’у находить все файлы с кодом у нас в проекте, и в конечном итоге наш composer.json будет выглядеть вот так:

{     "name": "zhukmax/gmail",     "description": "Package for easy using Gmail Api",     "type": "library",     "license": "Apache-2.0",     "authors": [         {             "name": "ZhukMax",             "email": "zhukmax@ya.ru"         }     ],     "minimum-stability": "dev",     "require": {         "php": ">=7.1.0",         "google/apiclient": "^2.0",         "ext-json": "*"     },     "autoload": {         "psr-4": {             "Zhukmax\\Gmail\\": "src/"         }     } }

Заходим на github под своим аккаунтом (если нужно зарегестрируйтесь) и создаем новый репозиторий с названием gmail, так же стоит указать описание, лицензию и другие настройки.

Новый репозиторий на github
Новый репозиторий на github

Подключаем к уже созданому локально проекту новый репозиторий:

git init git remote add origin https://github.com/ZhukMax/gmail.git git config checkout.defaultRemote origin git pull origin main

Открываем папку с нашим проектов в любимом редакторе коде, я лично предпочитаю PhpStrorm, но вполне подойдет даже Notepad++. Создаем директорию src, в которой и будет располагаться основной код. Как видно из листинга выше, мы прописали именно эту папку для всех классов в namespace Zhukmax\Gmail.

Создаем директорию src
Создаем директорию src

На шаге два из официальной инструкции к работе с Gmail API (https://developers.google.com/gmail/api/quickstart/php#step_2_set_up_the_sample) нам требуется создать файл, в котором размещаем некоторые конфигурационные данные, функцию авторизации и сам код работы с API. Как раз конфигурацию и авторизацию мы и перенесем в наш пакет, чтобы при использовании можно было не заморачиваться с этим кодом и сразу заниматься тем, что необходимо на проекте. Поэтому создаем класс авторизации в src и добавляем в него функцию авторизации:

touch src/Auth.php
Класс авторизации
Класс авторизации

Пока что наш код не будет работать, так как функции авторизации нужны настройки: название приложения, путь к директории для хранения токена, путь к файлу credentials.json, который можно получить в консоли разработчика Google. А еще этот код можно улучшить и упростить работу с ним для конечного разработчика. Для начала создадим публичный конструктор и метод, который будет отдавать готовый к работе сервис, либо выбрасывать исключение (Exception), если произошла какая-то ошибка, а уже созданный сделаем приватным:

<?php  private $name; private $scope; private $credentialsPath; private $tokenPath;  public function __construct(array $params) {     if (!$params['credentials']) {       throw new Exception("Path to credentials is required");     }     $this->credentialsPath = $params['credentials'];      if (!$params['token']) {       throw new Exception("Path to token is required");     }     $this->tokenPath = $params['token'];     $this->name = $params['name'] ?? 'Gmail API PHP';     $this->scope = $params['scope'] ?? Google_Service_Gmail::GMAIL_READONLY; }  public function getService() {     $client = self::getClient();     return new Google_Service_Gmail($client); } 
Добавляем путь к токену
Добавляем путь к токену

Также предлагаю сделать небольшую декомпозицию основного метода, взятого нами из официальной документации. Во-первых, стоит вынести код, занимающийся сохранением файла токена в отдельный метод, во-вторых, запрос токена, если предыдущий просрочен или даже не существует:

<?php  private function makeNewToken(Google_Client $client) {     // Request authorization from the user.     $authUrl = $client->createAuthUrl();     printf("Open the following link in your browser:\n%s\n", $authUrl);     print 'Enter verification code: ';     $authCode = trim(fgets(STDIN));      // Exchange authorization code for an access token.     $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);     $client->setAccessToken($accessToken);      // Check to see if there was an error.     if (array_key_exists('error', $accessToken)) {       throw new Exception(join(', ', $accessToken));     } }  private function saveToken(Google_Client $client) {     if (!file_exists(dirname($this->tokenPath))) {       mkdir(dirname($this->tokenPath), 0700, true);     }     file_put_contents($this->tokenPath, json_encode($client->getAccessToken())); } 

Конечно, еще хорошо бы покрыть весь наш код юнит-тестами, но это уже другая история.

Публикация библиотеки

Когда код библиотеки готов сделаем коммит и отправим все правки в репозиторий на github (или другой выбранный вами ранее):

git push origin main

Теперь скопируем ссылку на репозиторий:

На сайте packagist.org после авторизации переходим в раздел Submit, вставляем GitHub URL — ссылку на репозиторий и нажимаем Check и затем Submit

Готово, наша библиотка отправлена в публичное пространство и доступна для установок и использования.

Результат

Мы создали новую библиотеку, облегчающую работу с API, отправили ее публичный репозиторий и опубликовали для установки через composer. Теперь мы умеем делиться своими наработками и решениями с сообществом.

Репозиторий с кодом из статьи лежит по ссылке.


ссылка на оригинал статьи https://habr.com/ru/company/reksoft/blog/597049/


Комментарии

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

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