Заказать проект
Оставьте заявку для получения коммерческого предложения.
Заполните форму и мы вышлем Вам предложение в котором решим,
чем можем вам помочь.
Использование Composer в разработке под Bitrix

Использование Composer в разработке под Bitrix

13 Июля 2018
Максим Лиске
Back End Developer
Максим Лиске
следующая статья

Не часто можно встретить проект на Bitrix, в котором не используются обработчики событий. В большинстве случаев, разработчики просто пишут их в файле init.php, иногда создают файл handlers.php в той же папке и подключают его через include в инит. Если проект небольшой, к примеру информационный сайт с описанием достижений компании, то такой подход не принесет проблем, но на сложных или старых проектах мы можем наблюдать файл с “простыней” в несколько тысяч строк кода, попытки разобраться в котором могут стать головной болью. Также это касается собственных функций и классов, которые могут быть разбросаны по всему проекту.

Рассмотрим менее распространенную, но важную ситуацию: к проекту необходимо подключить стороннюю библиотеку. Всё происходит следующим образом: скачивается архив с библиотекой, распаковывается в какую-нибудь папку сайта и подключается через include в том месте, где нужен этот функционал. А если возникает необходимость обновить библиотеку? Перенести на другой проект? Что если библиотеке для работы необходима другая библиотека, которой у нас нет?

Справиться с этими проблемами нам поможет менеджер зависимостей — Composer. Основной задачей которого является установка необходимых нам версий библиотек и их зависимостей (которые требуются для работы нужных нам библиотек), а также предоставляет автоподгрузку классов как установленных библиотек, так и собственного кода. В этой статье рассмотрим базовые способы использования менеджера зависимостей, которые помогут структурировать проект и облегчат его дальнейшую поддержку.

Для начала установим Composer на проект. Сделать это очень просто - переходим на официальный сайт, скачиваем файл composer.phar и копируем его в папку /local/. Всё, Composer установлен. Далее необходимо указать зависимости, которые используются на проекте. Делается это через файл composer.json. Для того чтоб использовать только автоподгрузку классов достаточно прописать в нем следующее:

{
    "autoload": {
        "psr-4": {
            "Lib\\": "lib/"
        }
    }
}

Разберем по порядку что это значит: 

  • autoload - обозначает секцию где мы описываем автоподгрузку классов.
  • psr-4 - указываем способ подключения классов, в данном случае это спецификация автоподгрузки классов из путей файлов. Больше прочитать об этом стандарте можно тут.
  • "Avivi\\": "lib/" - базовое пространство имен и путь до папки, в которой описаны классы. Название для пространства имен можно указать любое, два обратных слеша после названия обязательны.

После этого сохраняем файл composer.json рядом с файлом composer.phar, подключаемся к серверу по ssh, переходим в папку /local/ и вводим команду:

php composer.phar install
Composer сам скачает всё что ему требуется. Далее подключаем в самом начале init.php файл /local/vendor/autoload.php.
require $_SERVER["DOCUMENT_ROOT"] . "/local/vendor/autoload.php";
Для примера напишем простой обработчик события OnBeforeIBlockElementUpdate. В init.php пишем:

Обратите внимание на строку

"Avivi\Handlers\Iblock\IblockElementHandlers", 
Таким образом мы указываем загрузчику где искать нужный нам класс. Фактический путь до файла выглядит так: <document root>/local/lib/Handlers/Iblock/IblockElementHandlers.php.

Содержимое файла IblockElementHandlers.php:
 
namespace Avivi\Handlers\Iblock;

class IblockElementHandlers
{
    function OnBeforeIBlockElementUpdateHandler(&$arFields)
    {
        file_put_contents(
            $_SERVER['DOCUMENT_ROOT'].'/log/update_log.txt', 
            date("d.m.Y H:i:s") . " -> " . $arFields['ID'] . "\n", 
            FILE_APPEND
        );
    }
}

Тут стоит остановиться подробнее на строке с объявление пространства имен: namespace Avivi\Handlers\Iblock;

Подобная строка должна присутствовать в каждом файле с классами. На первом месте базовое пространство имен, которое мы указывали в файле composer.json. Далее подпространства, которые соответствуют названиям папок в которых лежит файл с классом. Имя класса должно быть таким же как название файла, в котором он находится с соблюдением регистра.

Думаю, на данном этапе уже видна основная идея такого подхода: классы рассортированы по папкам в зависимости от того что класс делает и к какому модулю относится. Из объявления обработчика в init.php можно легко понять где находится этот класс. Поддерживать структурированный подобным образом код намного проще чем один файл в котором описаны все обработчики.

Приведем еще один простой пример не связанный с обработкой событий. Создадим в папке /local/lib/ папку Request, а в ней файл CurrencyRate.php:

namespace Avivi\Request;

class CurrencyRate
{
    public static function usdToUah()
    {
        $url = "http://free.currencyconverterapi.com/api/v5/convert?q=USD_UAH&compact=y";
        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}
Теперь на любой странице, в любом месте сайта можем вывести курс гривны относительно доллара:
$currencyRate = Avivi\Request\CurrencyRate::usdToUah()

Теперь давайте рассмотрим подключение сторонних библиотек к проекту. Для примера установим библиотеку fzaninotto/faker. Установить библиотеку на проект можно разными способами.

  1. Добавить в файл composer.json секцию require:

{
    "autoload": {
        "psr-4": {
            "Avivi\\": "lib/"
        }
    }
   "require": {
        "fzaninotto/faker": "1.7.*"
    }
}

Если в дальнейшем потребуется установить еще какие-нибудь библиотеки, то их нужно будет просто дописать в эту секцию в формате: “<имя разработчика>/<имя библиотеки>”: “версия”.

Сохраняем файл и вводим в консоли: php composer.phar install. Библиотека вместе со всеми зависимостями будет установлена в папку vendor.

2. Написать в консоли php composer.phar require fzaninotto/faker 1.7.*

Результат выполнения будет примерно следующий:


В этом случае Composer сам добавит запись в composer.json. Теперь мы можем использовать эту библиотеку в любом месте проекта:

$faker = Faker\Factory::create();
echo $faker->name;

Также теперь у нас в папке /local/ появился файл composer.lock. В нем хранится информация об установленных библиотеках и их версиях. Как вы могли заметить в composer.json для библиотеки faker версия указана “1.7.*”. Это означает что будет установлена версия >=1.7.0 но <1.8.0. Если на момент переноса изменений на “боевой” сайт выйдет новая версия, которая отвечает этому условию, то установится именно она, что может привести к ошибкам. Для этого и нужен файл composer.lock в котором указана точная версия, которая была установлена. Также этот файл нужен новым разработчикам на проекте, чтоб иметь возможность установить в своем тестовом окружении нужные версии библиотек. Если на проекте используется гит, то в репозиторий стоит добавлять только файл composer.lock, а файл composer.json добавить в .gitignore.

Надеюсь, я сумел продемонстрировать что Composer является прекрасным инструментом для структурирования кода и соблюдения таких принципов программирования как DRY (Don't Repeat Yourself) и KISS (Keep It Simple Stupid). Пишите понятный и поддерживаемый код ;)

P.S. Полезные ссылки:

  1. Официальная документация: https://getcomposer.org/doc.

  2. Дефолтный репозиторий пакетов: https://packagist.org/.

  3. Описание спецификаций PSR: https://www.php-fig.org/psr/.


Need help?

Ask a question.

Chat Now
Записаться На Консультацию
Записаться На Консультацию
Мы свяжемся
с вами
в течении
10 минут
laptop
Мы свяжемся с вами в течении 10 минут