Автоматичне підключення модулів у Бітрікс

Як відомо при розробці на Bitrix Framework програміст повинен сам піклуватися про підключення необхідних модулів за допомогою методу CModule :: IncludeModule. Причому підключати модулі необхідно скрізь, де відбувається звернення до api цих модулів. У кожному компоненті, шаблоні, скрипті, функції, методі.

А в чому, власне, проблема?

У невеликих проектах, можливо, це не становить ніякої складності, але у відносно великих проектах може набити оскому навіть самому невибаглива програмісту.

Ось простий, наочний приклад, хоч і не дуже життєвий:

Тут ми бачимо дві функції, які через api Інфоблоки отримують списки розділів. Нам заздалегідь невідомо в якому порядку будуть викликатися ці функції і чи будуть взагалі викликатися на даному хіті. Тому доводиться використовувати CModule :: IncludeModule в кожній з них. Це призводить до захаращення коду непотрібними конструкціями, погіршує його читабельність. Та й постійно доводиться стежити, щоб всі модулі були підключені. Все це створює, хоч і невеликі, але все ж незручності при розробці, ускладнює супровід коду. Особливо актуально для великих проектів.

легко забути

CModule :: IncludeModule ще неприємний тим, що про необхідність його використання легко забути. Справа в тому, що він не завжди потрібен для нормального функціонування вашого коду і ваш код до пори до часу буде працювати і без нього.

Таке можливо, наприклад, коли перед кодом, виконується компонент, який і підключає необхідний модуль. В цьому випадку код буде прекрасно працювати незалежно від наявності в ньому CModule :: IncludeModule. Але що станеться, якщо адміністратор забажає відключити цей компонент? Правильно, fatal error.

Може бути для когось постійний виклик CModule :: IncludeModule не представляє ніякої складності, але навіщо ж робити вручну те, що можна змусити виконуватися автоматично. Тим більше, що реалізується Автопідключення модулів всього лише кількома рядками коду:

Пишемо цей код, наприклад, в init.php і про ручному підключенні модулів можна забути раз і назавжди.

Проблема позначена, рішення знайдено. Далі буде багато букв про те, як це працює.

Як це працює?

У Бітрікс є свій автозавантажувач класів, який працює на основі карти класів. Ця карта формується при підключенні модулів. При підключенні кожен модуль реєструє свої класи в карті класів Автозавантажувач.

Відповідно, якщо модуль не підключений, то автозавантажувач Бітрікс нічого не знає про його класах і не зможе підключити їх, коли це буде необхідно. У підсумку ми бачимо fatal error, якщо використовуємо клас без підключення модуля.

Суть рішення полягає в тому, щоб зареєструвати в стеці Автозавантажувач ще один обробник. Управління до цього обробника буде доходити тільки в тому випадку якщо модуль не підключений. Оброблювач виконує наступні функції:

  1. Визначення до якого модулю відноситься необхідний клас
  2. Підключення цього модуля
  3. Передача управління Автозавантажувач Бітрікс

Чий це клас?

Автозавантажувач модулів повинен визначити до якого модулю відноситься клас. В наведеному вище прикладі для цього використовується карта класів, в якій прописано відповідність класів модулів. Це найпростіше рішення. Карта статична, вона зашита в коді. Її потрібно підтримувати в актуальному стані, вручну дописувати нові класи, що не дуже зручно.

Насправді ця карта класів, хоч і дещо в іншому вигляді, все ж таки присутня всередині бітріксового Автозавантажувач. Можливо існує спосіб витягти її, наприклад за допомогою Reflection. У цьому випадку необхідність вручну підтримувати карту класів відпадає.

А як же функції?

А функції в прольоті. У PHP отсутствуем механізм автозавантаження функцій. Тому якщо ви хочете використовувати, наприклад, функцію stemming. то будьте ласкаві попередньо підключити модуль пошуку search.

Тепер пропоную поглянути з висоти пташиного польоту на те, як буде працювати автозавантаження класів з встановленим Автозавантажувач модулів.

Припустимо у нас все ще не підключений модуль Інфоблоки і ми намагаємося виконати наступний код:

  1. Клас CIBlockElement ще не був оголошений і PHP покладає почесний обов'язок знайти і підключити зниклий клас на перший обробник з стека автозавантаження. Тобто на автозавантажувач Бітрікс.
  2. Автозавантажувач Бітрікс, безуспішно намагаючись знайти CIBlockElement, втрачає довіру PHP.
  3. PHP, щоб виправити становище, передає управління наступному оброблювачу, тобто нашому Автозавантажувач модулів.
  4. Автозавантажувач модулів визначає, що CIBlockElement належить модулю iblock і підключає цей модуль, після чого передає управління Автозавантажувач Бітрікс.
  5. Автозавантажувач Бітрікс, не вірячи своєму щастю, знаходить клас CIBlockElement в своїй карті класів і, нарешті, підключає його.
  6. Профіт!

Таким чином, легким рухом руки, ми позбавили себе від ще однієї рутинної роботи і зробили процес розробки на Bitrix трохи приємніше.

Схожі статті