В продолжение моей предыдущей статьи на эту тему, решил пересмотреть и переосмыслить то, с чем приходилось работать в течение полугода. В целом, модель годная, но при использовании вскрываются некоторые мелкие недостатки, которые удобнее было бы организовать по другому. Итак
Классы и библиотеки
В 21 веке без автозагрузки уже никуда. Сейчас активно использую на всех своих проектах автозагрузку по стандарту psr-4. Кто до сих пор не знаком со стандартами, разрабатываемыми PHP-FIG — то бегом знакомиться.
В директории /local у меня теперь существует папочка /classes, которая и содержит в себе все необходимые классы. Единственный мой класс, который подключается вручную в init.php — \Mx\Psr4Autoloader. Там же я регистрирую соответствие пространства имен и директории на сервере, а после этого класс уже делает все за меня — мне остается лишь соблюдать структуру директорий и правила именования файлов.
1 2 3 4 5 6 |
<?php require_once(__DIR__ . '/../local/classes/Mx/Psr4Autoloader.php'); $psr4 = new \Mx\Psr4Autoloader(); $psr4->addNamespace('Mx', __DIR__ . '/../local/classes/Mx/'); $psr4->register(); |
Большинство современных библиотек поддерживает стандарты автозагрузки (psr-4 или его предка psr-0), не стесняйтесь добавлять реализацию для этих автозагрузчиков и использовать их, подключая сторонние библиотеки. Это справедливо только для тех библиотек, которые еще по каким-то причинам не опубликованы в packagist или на гитхабе. С остальными же все сильно проще, они легко подключаются с помощью composer.
Для хранения проектного кода я сейчас в большей степени использую классы, а значит все правила, описанные выше, применяются и к обычному коду для битрикса. Я принял для себя следующую структуру (Mx — это краткое имя вендора, компании в которой я работаю ):
/local/classes/Mx/Main — все, что относится к главному модулю, а именно
/local/classes/Mx/Main/Component/ — дополнения функционала компонентов. Пока-что тут только базовый класс, который я использую для создания всех своих компонент
/local/classes/Mx/Main/EventHandler — обработчики событий, для них я использую свой автозагрузчик, о котором чуть ниже
/local/classes/Mx/Main/Agent/ — различные агенты, которые тоже можно дробить по принадлежности к функционалу
и так далее .. Можно придумать очень много, и будет все разложено «по полочкам». Мне — удобно. А вам?
Обработчики событий
Для обработчиков я использую нечто подобное psr-4 автозагрузчику, только переписанному на свой лад. Принцип тот же — есть класс, который задает соответствие директории и пространства имен. В этом классе есть метод, который регистрирует все эти соответствия и автоматически вызывает addEventHandler для всех найденных обработчиков.
1 2 3 4 5 |
<?php $el = new \Mx\Main\EventListener(); $el->addNamespace('\\Mx\\Main\\EventHandler', __DIR__ . '/../local/classes/Mx/Main/EventHandler'); $el->register(); |
А в реализации метода register как раз и содержится вся «магия». Помимо этого есть также и базовый класс для всех обработчиков событий, который позволяет обмениваться данными между обработчиками, управлять порядком вызова обработчиков, да и все что душе угодно можно к нему прикрутить. Мне оч. нравится
Зависимости
Про Composer я уже писал, и там тоже нужно статью несколько дополнить, чем займусь в ближайшее время. А сейчас хочу лишь напомнить, что есть такая замечательная штука, и нет ни одной причины, чтобы не использовать ее.
Кстати говоря — есть возможность подключать не только обычные классы-библиотеки, но и компоненты Symfony. Есть возможность нативно подключать даже битриксовые библиотеки/компоненты/шаблоны (в этом нам поможет composer/installers). В общем — дерзайте, вещь нужная и полезная.
На доработку
Пока остается еще неразрешенная проблема с фронтенд-библиотеками. Не нравится мне моя текущая система. Хочу подцепить к битриксу BowerPHP, организовав хранение и управление зависимостями. А там может получится и грамотный автозагрузчик сделать на основании конфигов Bower.
Также в планах обернуть все описанное выше в небольшой модуль, чтобы цеплять его к проекту через composer. Работу уже начал, скоро будет, тогда и опубликую.
UPD. А вот и модуль
UPD2. Продолжение статьи