Использование Composer для генерации автозагрузчика, поддерживающего legacy-код

в 4:11, , рубрики: composer, php, метки:

В настоящий момент во многих проектах с богатым наследием код представляет собой смесь из различных подходов, от PHP 3 до PHP 5.

В PHP 3 мы использовали библиотеки функций, файлы подключения к базе данных, файлы переопределения настроек php.ini и так далее.

В PHP 4 и 5 мы создавали классы, именование файлов которых было сильно кастомизировано, от package/class.myclass.inc до Package/MyClass.php.

В эпоху PHP 5 мы получили стандарт PSR-0, описывающий стандарт именования файлов классов PHP для повышения совместимости их автозагрузки.

Код постепенно начал превращаться в не очень приятное месиво из require_once и spl_autoload_register. Прямо скажем, месиво не сильно управляемое и время от времени приводящее к фатальным ошибкам «функция не существует» или «класс не существует» при разработке нового кода.

И вот, внезапно к нам на помощь пришёл менеджер зависимостей Composer (github-репозиторий).

Хочу подчеркнуть, что Composer не является только лишь генератором автозагрузчика. Задачи, которые он выполняет намного более широки и интересны.

Давайте посмотрим, как мы можем применить Composer для генерации автозагрузчика для нашего legacy-кода.

Компоненты Composer'а

Composer состоит из PHP-пакета composer.phar и json-схемы composer.json (помещается в ту же папку, в которой находится composer.phar).

Схема, описываемая в composer.json, имеет несколько разделов. Нас же интересует только раздел «autoload».

Раздел autoload схемы composer.json

Раздел может включать один или несколько подразделов: psr-0, classmap, files — и отвечает за генерацию автозагрузчика описанных в подразделе классов и файлов.

Подраздел psr-0

Подраздел psr-0 отвечает за добавление в автозагрузчик пакетов, именование в которых удовлетворяет требованиям стандарта PSR-0.

Подраздел представляет собой объект, свойствами которого является имя пакета или поставщика, а значением свойств — директория, в которой находится директория пакета или директория поставщика с поддиректориями пакетов этого поставщика (см. PSR-0).

Предположим, мы имеем поставщика MyVendor и отдельный пакет MyPackage:

composer.json
composer.phar
lib/
    MyVendor/
includes/
    MyPackage/

Для генерации автозагрузчика, нам необходимо добавить следующий код в composer.json:

{
    "autoload": {
        "psr-0": {
            "MyVendor": "lib/",
            "MyPackage": "includes/"
        }
    }
}

Подраздел classmap

Подраздел classmap отвечает за описание файлов классов, именование которых не соответствует стандарту PSR-0.

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

Существует возможность описания отдельного файла класса и описания директории для последующего создания описания всех файлов классов, находящихся в директории (рекурсивно).

Предположим, у нас есть директория MyClasses с набором классов с различным именованием и файл class.myclass.php, содержащий какой-то отдельный класс, который нам необходимо загружать:

composer.json
composer.phar
MyClasses/
SomeDir/
    class.myclass.php

Для генерации автозагрузчика, нам необходимо добавить следующий код в composer.json:

{
    "autoload": {
        "classmap": [
            "MyClasses/",
            "SomeDir/class.myclass.php"
        ]
    }
}

Подраздел files

Подраздел files отвечает за описание файлов, которые нам необходимо подключать в самом начале исполнения приложения.

Подраздел представляет собой массив файлов, которые должны быть подключены.

Предположим, что у нас есть файлы functions.php и db_connect.php, которые должны быть последовательно подключены перед исполнением приложения:

composer.json
composer.phar
functions/
    functions.php
    db_connect.php

Для генерации автозагрузчика, нам необходимо добавить следующий код в composer.json:

{
    "autoload": {
        "files": [
            "functions.php",
            "db_connect.php"
        ]
    }
}

Собираем всё в кучу

Давайте напишем файл, который позволит нам иметь автозагрузчик, обслуживающий все описанные выше ситуации:

{
    "autoload": {
        "psr-0": {
            "MyVendor": "lib/",
            "MyPackage": "includes/"
        }, 
        "classmap": [
            "MyClasses/",
            "SomeDir/class.myclass.php"
        ],
        "files": [
            "functions/functions.php",
            "functions/db_connect.php"
        ]
    }
}

Генерируем автозагрузчик

После того, как мы описали все необходимые нам пакеты и файлы, генерируем автозагрузчик:

php composer.phar install

Если всё прошло успешно, подключаем сгенерированный нами файл в bootstrap-файл (предполагаем, что bootstrap-файл лежит в той же директории, в которой лежит composer.phar) своего проекта:

$loader = require_once __DIR__.'/vendor/autoload.php';

Всё, требуемые файлы загружаются автоматически.

Объект автозагрузчика, сохранённый в $loader, можем использовать для ручного добавления файлов и пакетов в автозагрузчик.

Заключение

Composer — это гораздо больше, чем просто генератор автозагрузчика. Рекомендую более пристально присмотреться к этому проекту.

Всем удачи на пути к построению надёжных приложений, построенных на красивых решениях.

Автор: ohmytribe

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js