Битрикс: пытаемся разобраться. Часть 1: Устройство и технические свойства платформы

Компания 1С-Битрикс и ее продукты (CMS и корпоративный портал) вызывают много вопросов и обсуждений как в интернете, так и в жизни. Выходят новые версии, идут семинары, компания занимается активной маркетинговой деятельностью, работает партнерская сеть, а вопросов со стороны профессионального сообщества меньше не становится.
Эта статья – попытка разобраться в частых вопросах и проблемах и сформировать общее понимание ситуации.

Немного предыстории и авторской позиции.
ИНТЕРВОЛГА работает на Битриксе без малого 2 года. Мы развивали свою систему, пробовали другие коробочные системы. Из 300 сделанных нами проектов лишь около 70 -- на Битриксе.
Так что опыт работы на других системах есть и солидный. Я понимаю и что такое свой код, и что такое разработка на опенсорсе, и что такое другие коробочные системы.
Теперь работаем на Битриксе, и в целом – довольны. Не хочу сейчас о личных впечатлениях, скажу главное: я безусловно не являюсь объективным.
Далее мое субъективное восприятие.

Цель статьи: подумать вслух.
Хочу получить обратную связь и дополнить собственное понимание.

В основном буду говорить не о маркетинге и лозунгах, а о прикладной стороне системы, как я ее понимаю.
Как она построена, как делать на ней проекты, как чувствуют себя пользователи, как работают партнеры. Как система развивается сама и как она готова к развитию со стороны.

Обсуждая технологии, будем говорить не об абстрактной красоте кода и применении всех возможных нанотехнологий, а только о технических аспектах, создающих бизнес-преимущества.
То есть:
Довод «ОRM нужна, ибо это круто» мало что значит.
Довод «убогая реализация мастеров установки (класс Wizard) мешает делать установщики для сложных тиражных продуктов» принимается, если это правда.

Я хочу построить по возможности полный перечень вопросов (скажем, основываясь на тех, которые можно найти в яндексе по словам «битрикс @#$%"») и разобраться. Отделить, так сказать.

Задача, на мой взгляд, грандиозная, так что решена в меру моих скромных возможностей.

Часть 1. Устройство и технические свойства платформы 1С-Битрикс. Возможности, требования, производительность. Версия PHP, разделение логики и представления, шаблонизация, XSLT, «Инфоблоки: База в базе», запросы.

1.    Он сделан на древнем как помет мамонта PHP 4. Это не круто, пещерный код!


Ответ на каждый вопрос буду разбивать на три куска: суть («смысл и важность вопроса»), + (достоинства решения Битрикcом) и - (недостатки решения Битриксом)

Суть.
Для бизнеса, для клиента, для внедрения версия php это один из последних технических вопросов. Думаю, менее важный, чем версия серверной ОС в офисе или тип принтеров: МФУ или классические лазерные работяги.
Для программиста, натягивающего дизайн или делающего компоненты, это тоже в общем мелочь. Ну сохранено много чего для совместимости, и бог с этим.
Для кого это важно? В чем вообще вопрос? В том, что обеспечение совместимости с версией 4, выпущенной (страшно сказать) в 2000 году, требует соблюдения морально устаревших и технически избыточных конструкций и запрещает использование многого важного, удобного и в целом – правильного.
Коротко говоря: больше трудного в чтении глупого кода.

+
В 2010 году Битрикс прекратил практику поддержки совместимости кода системы с PHP4. Теперь все пишется без поддержки PHP4.
Как я понимаю, есть планы по наведению порядка в старом коде.
Вы спросите: а зачем его вообще так писали? Был ли смысл работать с поддержкой версии 4, ведь когда Битрикс всерьез выходил на рынок, уже была и набирала популярность версия 5.
Это интересный вопрос. Думаю, что система так долго сохраняла эту совместимость потому, что хостинговые компании переходили на php5 относительно медленно и было важно не создавать препятствий для внедрений. Кроме того -- совместимость новых версий Битрикса со всем, что было написано ранее, поддерживается разработчиками постоянно. Для партнеров, поддерживающих разные проекты, уверенность в такой совместимости является на мой взгляд одной из самых важных положительных сторон.

-
Конечно, все что делалось давно и с тех пор не переписано, изобилует кодом, совместимым с php4. Если надо с ним работать, кастомизировать и развивать, придется возиться. Если вас такой код бесит -- придется сжать зубы.

2.    Где разделение логики и представления (тут же каша из php, HTML, css, js и SQL!)

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

Как это делать? Часто хотят разделить по критерию языка программирования. Давайте возьмем любой веб-продукт. Там 4 языка будет точно. HTML+css (посчитаем за 1 язык), серверные скрипты, клиентские скрипты и язык СУБД. Иногда -- больше. И переход между языками совершенно не означает смены роли соответствующего куска кода. Часто куски, на которые вы порежете, будут использоваться ровно 1 раз. Какую пользу принесет такое разделение? Никакой. Представьте себе полный список фрагментов HTML или SQL-кода, которые есть в проекте. Как их складировать, как именовать, как вызывать?
Конечно, критерий разделения должен быть другим. Разделять логику, данные, языки, сущности на независимо и удобно редактируемые элементы нужно по критерию частоты правки. Нужно смотреть, кто и в каких обстоятельствах эту правку будет выполнять. Соответственно и сами средства редактирования нужно создавать именно с учетом этого критерия.

В вебе и программировании вообще есть популярный миф, что логику, данные и представления легко и очевидно можно отделить друг от друга. Что решение этой задачи однозначно, и кто делает не так, как кажется говорящему -- ленивый дурак. Если немного подумать, становится очевидно что логика, данные и представления легко переходят между собой в зависимости от того, с какого уровня абстракции вы смотрите на задачу. Например, html-код шаблона для разработчика сайта это безусловно представление, для браузера это код, а для ядра CMS это данные.

+
Основная претензия к Битриксу в этой части -- разработчики, впервые видящие код шаблона любого компонента, например списка новостей, ужасаются циклу, каше из php и HTML (и js изредка можно встретить) и сразу говорят что Битрикс написан на каше из спагетти-кода и они с ним работать отказываются.
Попробуем разобраться.
Когда задается вопрос про кашу, сразу понятно что смотрел человек. Человек открыл код шаблона, увидел цикл с HTML вперемешку с php и решил, что Битрикс плохо.

Так вот, про кашу в шаблоне. Это шаблон, он для вывода. Все данные уже собраны, запросы отработали, понятно что и куда мы выводим, даже отлов угроз уже прошел. Это последнее звено в пищевой цепочке кода и данных. Тут логика вывода действительно смешана с оформлением, и это правильно.
Это не нравится фанатикам, фанатики в своих CMS делают иначе: там часто код вызывает шаблон, который опять вызывает код, в котором опять вызывается шаблон. Все это обрабатывается через eval и практически не поддается отладке Зато очень красиво.
То, как сделано в Битриксе, поддается любой отладке и тратит минимум ресурсов.
То, что видно в коде шаблона, является представлением. Код этого представления будет переписан на 90% при редизайне вместе с php и HTML. Это не бизнес-логика, это логика вывода и она в Битриксе выведена в отдельную сущность - код шаблона.
Код, реализующий бизнес-логику, запрашивающий и обрабатывающий данные, находится в других местах -- компонентах и модулях. О них мы поговорим дальше.
Я убежден, что логика, представления и данные в Битриксе разделены самым разумным для задач CMS образом.

-
Действительно, где данные, где представления и где разные сорта кода -- разобраться часто очень непросто.
Во многих случаях программисты и не хотят об этом думать, у них другой подход. Поскольку далеко не все видят разницу между обращением на языке php к извлеченным данным для целей вывода и тяжелыми запросами к бд или вызовам функций API, то в шаблоне можно писать любой php-код. Можно прямое, даже не API-шное обращение к базе написать. Можно написать десяток строк на API и решить задачу. Битрикс этим очень развращает разработчика. Не запрещено писать бизнес- логику в шаблонах и HTML в компонентах.
Прекрасно помню как я сам, не разобравшись особо в компоненте и поленившись его кастомизировать, дописал прямо в index.php сайта пару неприятных GetList. Потом переделали, но впечатление яркое осталось. И очень часто это впечатление от сделанного с применением Битрикса безобразия переносится на сам Битрикс.

Вывод:
В собственном коде и по идеологии Битрикса задача решена нормально, а вот привитием хороших манер и практик Битрикс почти не занимается. Дает слишком много свободы. Style guides, Code conventions, Code review - все на совести разработчика.
Понятно, что обычно и разработчик этим не занимается.

3.    Где шаблонизатор?

Суть.
Часто в веб-системах выделяют функционально независимую часть, которая должна  получить данные (вход) и сгенерировать представление (выход). Поскольку веб-представления бывают сложны не только по виду, не только по структуре текста, но и по логике вывода (скажем, колоночный вывод, различные шаблоны вывода в зависимости от уровня доступа пользователя), то язык шаблонизатора, особенно функционального, вполне сопоставим с языком разметки или даже программирования.
При этом язык php уже сам является шаблонизатором, так как умеет оставлять без изменения те части текста, которые находятся вне его маркеров.
Как правило, нет никакого прикладного смысла в том, что на языке-шаблонизаторе писать поверх еще 1 шаблонизатор. Польза от этого (сомнительная) только одна: ограничить возможность написания кода для редактора шаблонов.
Отдельно поговорим про XML и xslt как альтернативу классическим “грязным php-шаблонам” чуть далее.

+
В Битриксе никакого отдельного шаблонизатора нет. Битрикс использует php. Хорошо это или плохо -- однозначно сказать сложно. Я вижу больше плюсов. Хотя бы то, что его не надо учить. В Битриксе есть что учить и без шаблонизатора.
Разумеется, все что можно вообще сделать на языке программирования, можно сделать в шаблоне, ведь это просто php.

-
То, что шаблоны пишутся прямо на php, предоставляет широчайшие возможности для г#$%кода. Ничто не мешает написать прямо в тексте шаблона вызов другого компонента, прямое или API-шное обращение к БД, или любую другую ерунду, не рекомендованную по идеологии в этом месте. Битрикс это не контролирует.

4.    XML/XSLT. Почему не применяется современный, технологичный, стандартизованный подход к шаблонизации на основе xslt-преобразований данных в представления?

Суть.
Суть идеи XSLT проста и красива. Код системы (бизнес-логика) реализует все функции и готовит данные в формате xml.
В xml никакого оформления нет, одни данные и разметка, отражающая их структуру.
Затем с помощью xslt-преобразований делается представление.
В xslt-преобразованиях нет бизнес-логики. Там нельзя написать запрос к БД.
Технологически идея xslt более красива, чем грязное, не поддающееся повторному использованию и развязывающее руки г@#$%кодерам применение php-шаблонов.
В Битриксе XSLT нет.

+
PHP-шаблонизация известна всем, стандартна, производительна и гибка. XSLT надо учить, его производительность и гибкость не всеми подтверждаются.
Есть мнение, что только с таким PHP- шаблонизатором можно быстро знакомиться с системой и начинать поддержку.
Есть множество экспертных мнений, что PHP-шаблоны оправдывают себя экономически и производственно, в отличие от XSLT, Smarty и прочего.
Независимо от того, родился плохой или хороший код шаблона, его все равно не будут редактировать. Его перепишут.

-
PHP-шаблоны позволяют и даже поощряют написание плохого кода.
Технология XSLT менее подвержена этому недостатку.
Есть мнение, что только с XLST-шаблонизатором можно качественно и долго развивать проекты, повышая эффективность сотрудников и зарабатывая деньги.
Есть множество экспертных мнений, что XSLT-шаблоны оправдывают себя экономически и производственно, в отличие от PHP, Smarty и прочего.
Есть масса хороших специалистов, которые верят в мощь xslt. Почему бы Битриксу не включить его поддержку? Если бизнес Битрикса в создании новых возможностей для партнеров и есть те, кто скажет, что хочет развивать свои проекты на xslt – почему нет? Я не готов судить о том, насколько это сложно и революционно, но в минусы запишу.

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

5.    Инфоблоки или “База в базе”

Частенько при обсуждении Битрикса новичками рождается текст вроде такого "ужас, с этой структурой данных невозможно работать напрямую, посмотрите как они хранят свойства элементов".
Действительно, на первый взгляд выглядит странно. Но только на первый. Точно так же поступают для хранения данных редактируемой структуры 1С, invision power board, wordpress и тысячи других веб- и не-веб-приложений.
Не знаю как это называется по-умному, я привык называть это решение "база данных в базе данных".
Подход заключается в том, что в физической структуре БД создаются 4 таблицы, не меняющиеся при изменении структуры данных: типы объектов, экземпляры объектов, свойства объектов и значения свойств объектов.

+
Плюсы лежат на поверхности: удобный контроль над данными такой структуры из своего приложения, универсальность методов, общая структура данных для любого проекта, возможность многократно менять типы данных для полей без уничтожения самих данных (попробуйте без этого механизма сменить тип поля в БД по кругу: текст-дата-число-текст и посмотрите что будет).

-
Минусы тоже очевидны: тормоза и непрозрачность при прямом доступе к данным.
Начнем с последнего. Честно, не понимаю что мешает получать доступ к данным с применением родного для них API. Что за кайф разбираться в хитросплетениях чужой структуры данных при наличии развитого API?
Тормоза - вопрос важный, но далеко не однозначный.
Действительно, при хранении всех свойств в одной таблице извлечение значений, например 20 свойств, приведет к 20 джоинам. Сортировки и поиски тоже не добавят красоты запросу.
Если же есть сложная логика вроде: все товары (таблицей), поставщика А за прошлый год, брендов Electrolux и Bosch, с гарантией от 9 мес и имеющиеся в наличии на складах Московской области, то не слишком сложный по сути запрос (ну на вид джоинов 7 максимум, и даже без левых), оборачивается сотней джоинов. Штатно из них можно опять сделать 7 (ну 10 с учетом системных таблиц), но этим надо заниматься.
Поговорим о запросах.

6.    Тяжелые длинные непонятные запросы к базе данных (примеров масса на различных форумах и в любых проектах)

Суть
Код Битрикса порождает очень большие запросы. Несколько экранов не очень понятного SQL традиционно пугают людей, которые редко пишут запросы сложнее sel ect * fr om ... where id=... и уверены что объединение таблиц по условиям делается через where так же производительно, как через on.
Давайте попробуем разобраться в этой очень сложной теме, которая включает вопросы узкотехнологические, вроде производительности конкретных выборок, вопросы удобного применения технологий работы с БД в больших развиваемых проектах на растущей CMS, вопросы стоимости владения и поддержки.

Откуда это все вообще берется?
Есть инфоблоки, где быстро и комфортно создается структура данных. Есть стандартные компоненты, реализующие наиболее распространенные вещи. Есть API, позволяющее отправлять достаточно произвольные запросы.
Прямой доступ к БД неудобен и вообще говоря, противопоказан, так как физическая структура БД может измениться, а работа даже самого древнего API гарантирована.
Вы применяете компоненты, пишете свои, активно пользуетесь API, в итоге ваша достаточно высокоуровневая логика выборки превращается в запрос. Генератор запроса, несмотря на свою сложность, по сути выполняет довольно тупую работу по переводу логики, изложенной на высоком уровне, в обращения к конкретным полям конкретных таблиц по условиям.
Запрос получается совершенно неудробочитаемым.
Со вставками и удалениями все в общем так же.

-
Начнем с минусов
Сложные запросы очень велики и вы почти не можете влиять на их структуру. Если есть желание заняться их профилировкой и отладкой, вы фактически ограничены теми не слишком богатыми средствами изменения запроса, которые предлагает Битрикс. Порядок объединений, специфические условия на выборки,  локальные кеширующие временные таблицы -- у вас всего этого нет.
Запрос рождается системой.
В мощных СУБД есть умные и очень эффективные оптимизаторы запросов, которые готовы из говна сделать конфетку (а совсем плохие запросы такие СУБД даже не дают исполнять). Подавляющее большинство установок Битрикса работают на MySQL, чей оптимизатор достаточно слаб и для таких задач подходит мало. Разумно было бы разработать свой или интегрировать внешний, но насколько я понимаю, технологически эта задача очень сложна и решать ее всерьез Битрикс не готов.
В итоге мы имеем большие запросы, ограниченные средства их изменения с сохранением логики, и механизмы кеширования поверх всего этого.

+
Главный плюс. Запросы не надо писать руками. Создание сайта на Битриксе обычно предусматривает визуальную настройку готовых компонентов, создании структуры сайта и натягивание дизайна. Не в каждом проекте приходится кастомизировать компоненты, но даже эта работа не заставляет писать запросы. Есть API, до физической структур дела нет.
Вернемся к запросам.
Запросы велики, нелегко их менять, иногда все тупит.
Но:
- безопасность. Обертки над запросами решают задачу защиты от атак или глупостей.
- есть инфоблоки 2.0. Это включаемый галочкой в админке режим работы инфоблока, когда его поля переносятся в отдельную таблицу. Как правило -- здорово помогает при большом числе записей и опасности блокировок. Джоины, появившиеся для извлечения отдельных свойств, сливаются в один.
- большой запрос не всегда синоним долгого исполнения. Возьмите из вашего тяжелого проекта тяжелый запрос и сделайте explain в консоли. Вы удивитесь как хорошо он покрыт индексами и как мало там будет циклических переборов записей.
- в большинстве проектов нагрузка на sql (время исполнения) несущественна по сравнению с нагрузкой на процессор и затратами на интерпретацию скриптов. Проще говоря: тормозит не mysql, а php
- огромную роль играет правильность проектирования структуры данных, выбор связей и их реализация средствами системы инфоблоков или таблиц. Проще говоря: устранить тупняки гораздо правильнее грамотным проектированием, чем оптимизацией запроса, который Битрикс родил по вашим указаниям.
- кеширование позволяет сэкономить на времени исполнения запросов, а грамотное распределение логики по компонентам позволяет вообще их не вызывать. Есть правило: главная страница сайта (обычно не самая простая) не должна отправлять запросы к БД при включенном кеше. Если вы это сделали, что вам горя с того, что иногда будут вызываться тяжелые (на десятые доли секунды) запросы?
- выбор типа таблиц InnoDB/MyISAM с учетом специфики проекта и сервера тоже помогает.
- наиболее критичные по производительности вещи можно и нужно реализовывать не инфоблоками. Инфоблоки (база в базе) дают гибкость в ущерб производительности. Нужна производительность -- делайте таблицами, API для этого есть.
- недавно Битрикс сделал настраиваемую из админки кластеризацию БД на стандартных механизмах MySQL
- любой отдельно взятый медленный запрос можно ускорить на счет всего стека возможностей: от архитектуры проекта и данных до прямого тюнинга БД и запроса
- если проект тупит в целом, для нормального бизнеса обычно не проблема перейти на более серьезное железо. Купить хороший сервер стоит как 2-3 месяца работы хорошего специалиста. Арендовать – как 2 недели. И бизнесу это нравится. Есть мнение что другие свойства Битрикса экономят куда больше денег.
- для действительно серьезных задач есть Oracle и MS SQL. Большому кораблю -- нормальную СУБД.

Вывод по первой части.
Битрикс – специфическая система, удивительная на первый взгляд. Есть мнения что она ужасна и наполнена неправильными решениями, есть мнения что она проста и понятна, потому и работает.
Мое мнение в том, что этот набор простых и гибких решений хорошо работает. Он работает на клиента, он работает на бизнес студии, он работает на перспективу.
Несмотря на то что технические решения далеко не однозначны, я не вижу кому от них плохо.
Возможно, вы привыкли к другому. Система реализует особую идеологию, возможно не самую красивую, зато исключительно эффективную.
Если оно отличается от того, что вам близко и понятно, и вы недовольны, спросите себя, как эта система развивается 10 лет?
Как сохранена полная обратная совместимость до самых ранних версий? Как удается запускать 2 релиза в год? Вы знаете другую такую компанию?
Мне кажется, тут есть о чем подумать.

Часть 2: Идеология и архитектура платформы 1с-Битрикс. ООП, ORM, Паттерны проектирования, MVC

Часть 3: Битрикс для бизнеса. Взгляд сисадмина, разработчика, директора

Спасибо за внимание.

Комментарии (1)

...
  • Дмитрий
  • 19.08.2013 23:02:07
Спасибо за статью, очень познавательно. У самого опыт работы с различными web-фреймворками, в основном из мира Java - Spring, Java EE, Struts и т.д. Тут понадобилось сделать себе интернет-магазин. Увидев Битрикс понял что это то что нужно. Мощь и гибкость платформы видна невооруженным взглядом, но по официальной документации сложно провести параллели со стандартами web-разработки на других платформах. Ваши же статьи как раз и дают возможность все охватить сверху одним взглядом и понять что к чему. Спасибо!