Руководство Melbis Shop: оглавление
Для облегчения восприятия кода и совместимости модулей разных разработчиков мы настоятельно рекомендуем придерживаться следующих соглашений об именовании.
Корневые скрипты и HTML-шаблоны — нижний регистр, слова разделяются знаком подчёркивания:
index.php
page_catalog.php
main.htm
page_404.htm
item_product.htm
Модульные скрипты строятся по схеме из трёх частей, разделённых подчёркиванием:
{компания}_{группа}_{назначение}.php
melbis.
Для своих проектов выбирайте уникальный идентификатор: он отделит ваши
модули от штатных и от чужих, если вы подключите готовые наработки.Примеры:
melbis_base_page.php — базовый роутер страниц
melbis_store_card.php — карточка товара
melbis_cataloge.php — каталог
melbis_inc_logic_order.php — библиотека работы с заказом
melbis_block_slider.php — слайдер
melbis_client_auth.php — авторизация клиента
У библиотек частей четыре: слово inc занимает место
группы, а собственная группа библиотеки переезжает в следующую часть
имени — об этом ниже, в разделе «Группы модулей».
Кроме самого кода у каждого модуля есть параметры — кеш, входные данные, список таблиц, подключённые библиотеки. Они задаются в окне «Среда разработки», в правой панели рядом с редактором кода, и хранятся вместе с модулем. Подробнее это описано в разделе «Модульные скрипты».
Группа в имени модуля несёт смысловую нагрузку и определяет
отображение в дереве «Среды разработки». Зарезервирована только одна
группа — inc (допускается также
include или пустое значение). Модули с такой группой
являются библиотеками: у них не может быть HTML-шаблонов, и парсер их не
вызывает напрямую — их функции используются другими модулями.
Все остальные имена групп (base, store,
cataloge, basket, client,
block, cron и любые другие) вы определяете
самостоятельно исходя из архитектуры проекта. Группа — это просто способ
организовать модули в дереве файлов.
melbis_base_page.php — обычный модуль (группа base)
melbis_store_card.php — обычный модуль (группа store)
melbis_block_slider.php — обычный модуль (группа block)
У библиотек слово inc занимает место группы, поэтому
собственная группа переезжает в следующую часть имени:
{компания}_inc_{группа}_{назначение}.php
В дереве «Среды разработки» библиотеки раскладываются по этой группе
— рядом с обычными модулями и на том же уровне, но со своим значком.
Общей папки inc, куда сваливались бы все библиотеки
проекта, больше нет:
melbis
logic melbis_inc_logic_auth.php
melbis_inc_logic_common.php
melbis_inc_logic_order.php
melbis_inc_logic_order_calc.php
melbis_inc_logic_order_edit.php
page melbis_inc_page_callback.php
melbis_inc_page_menu.php
base melbis_base_footer.php
melbis_base_head.php
melbis_base_header.php
melbis_base_page.php
basket melbis_basket.php
cataloge melbis_cataloge.php
melbis_cataloge_sub.php
Так melbis_inc_logic_auth.php — группа
logic, назначение auth, а
melbis_inc_page_callback.php — группа page,
назначение callback. Назначение можно опустить, если
библиотека в группе одна: тогда имя —
{компания}_inc_{группа}.php.
Смысл в том, чтобы библиотека лежала рядом с модулями, которые ею
пользуются: melbis_inc_page_callback и
melbis_inc_page_menu служат модулям, строящим страницы
витрины, и собраны в группу page, а не растворены среди
всех прочих библиотек.
Модуль объявляет собственное пространство имён — имя
своего файла в верхнем регистре, — а главную функцию
называет Main. Именно эту функцию вызывает парсер:
// Файл: melbis_store_card.php
namespace MELBIS_STORE_CARD;
function Main($mVars)
{
...
}Исключение — библиотечные модули группы inc. Парсер их
не вызывает, поэтому функции Main у них нет. Вместо этого
они содержат набор функций, которые явно вызываются из других
модулей.
Вспомогательные функции модуля называются коротко, без приставок, а имя пишется PascalCase — каждое слово с заглавной, без подчёркиваний:
function Price($mTpl, $mId)
{
...
}
function Features($mTpl, $mId)
{
...
}Имя модуля стоит в строке namespace, и полное имя
функции — MELBIS_STORE_CARD\Price. Граница между модулем и
функцией здесь — обратный слеш, конструкция языка: её видят и глаз, и
инструменты — IDE и линтер раскладывают имя, не заглядывая в дерево
модулей, а поиск по Price находит и объявление, и вызовы.
Точку входа от вспомогательных функций отличает само имя
Main, закреплённое за ней.
Аббревиатуры пишутся как слова: SmsUrl,
XmlLoad — не SMSUrl.
Функции библиотечных модулей (inc)
именуются так же — в пространстве своей библиотеки:
// Файл: melbis_inc_logic_order.php
namespace MELBIS_INC_LOGIC_ORDER;
function Create(...) { ... }
function Load(...) { ... }
function GoodsAdd(...) { ... }Вызывающий модуль зовёт их через короткое имя библиотеки —
LOGIC_ORDER\GoodsAdd(...) (см. «Модули-библиотеки»).
Модули прошлых лет пространства не объявляют, и все их функции лежат в общем пространстве PHP. Поэтому имена в них несут приставку: главная функция называется именем файла в верхнем регистре, вспомогательные — тем же именем с Pascal-хвостом:
// Файл: melbis_store_card.php
function MELBIS_STORE_CARD($mVars) { ... }
function MELBIS_STORE_CARD_Price($mTpl, $mId) { ... }
function MELBIS_STORE_CARD_Features($mTpl, $mId) { ... }Границу имени здесь отмечает смена регистра: слева от неё — модуль,
справа — функция. Строчные хвосты (MELBIS_STORE_CARD_price)
тоже допустимы: PHP не различает регистр в именах функций.
Парсер ищет обе формы главной функции, так что такие модули работают
по-прежнему. При переводе модуля в пространство имён подчёркивание перед
хвостом становится обратным слешем —
MELBIS_STORE_CARD_Price превращается в
MELBIS_STORE_CARD\Price. Что ещё проверить при переводе — в
разделе «Модульные скрипты».
Комментарий стоит над строкой или блоком, к которому относится, и умещается в одну строку: он говорит, что делает следующий шаг, а не пересказывает код. Подробные объяснения — в документации, а не в исходнике.
Рядом с редактором кода в окне «Среда разработки» показано дерево функций модуля. Обычные комментарии в него не попадают, а заголовки двух видов попадают, и по ним модуль читается как оглавление.
Заголовок этапа — комментарий, под которым стоит строка из дефисов той же длины. В дереве он виден под своей функцией:
function Verify($mUserId, $mVersion, $mVersionBefore)
{
// Store options, blocked pairs
//-----------------------------
...
// Order options, blocked pairs
//-----------------------------
...
}Заголовок группы — комментарий между функциями, под
которым стоит строка знаков = до 100-й колонки, на ширину
шапки файла. В дереве группа становится папкой: функции, идущие за
заголовком, показаны внутри неё, до следующей группы или до конца
файла.
Функции модуля и библиотеки делятся на два раздела. Раздел — тот же заголовок группы, только имя стоит между тире; в дереве он выглядит разделительной линией.
// ————— Public —————
//==================================================================================================Main и функции, которые
вызываются по func. У библиотеки — другие модули. Раздел
пишется всегда, даже над одной функцией.LOGIC_COMMON\Rate, курс
валюты.Внутри раздела функции делятся на группы по темам — когда их много и
темы разные. Main модуля стоит в первой группе. Небольшому
разделу группы не нужны: функции идут прямо под ним.
// ————— Public —————
//==================================================================================================
// Actions
//==================================================================================================
/**
* Function Main
**/
function Main($mVars)Перед каждым заголовком — две пустые строки, после заголовка группы — тоже две, между разделом и его первой группой — одна.
Шапка модуля перечисляет его функции с пояснением в несколько слов. Пустая строка в шапке отделяет те же группы, что и заголовки в коде:
* Main - Runs what the form names
* Plus - Puts a goods in
* Minus - Takes a goods out
*
* Goods - Prints the basket goods
* Fields - Prints the buyer fieldsЗаголовки этапов ставятся в длинной функции, где этапов не меньше трёх; короткой функции они не нужны. Заголовок — не длиннее пяти слов: панель дерева узкая и обрезает длинные.
| Тип переменной | Правило | Пример |
|---|---|---|
| Входные параметры функции | Начинаются с $m, далее camelCase |
$mVars, $mTopicId, $mTpl |
| Локальные переменные | Нижний регистр, слова через _ |
$id, $item_count,
$command |
| PHP-константы | Верхний регистр, слова через _ |
MELBIS_CACHE, MELBIS_LANG |
В главной функции модуля массив входных параметров принято называть
$mVars.
Псевдоним таблицы — аббревиатура из первых букв слов её
имени (префикс {DBNICK}_ не считается):
{DBNICK}_user_task → ut,
{DBNICK}_user_group → ug,
{DBNICK}_user → u. Если таблица встречается в
запросе несколько раз или нужен признак роли — к аббревиатуре
добавляется признак через подчёркивание: u_author,
u_exec, ug_main.
Правило не косметическое: на нём построена подсказка полей в «Среде
разработки». Набранное ut. или u_author. IDE
сводит к таблицам, подпадающим под сокращение, и показывает их поля.
$command = "SELECT ut.id, ut.name, ut.state_key,
u_author.login AS author, u_exec.login AS executor
FROM {DBNICK}_user_task ut
LEFT JOIN {DBNICK}_user u_author
ON u_author.id = ut.user_id
LEFT JOIN {DBNICK}_user u_exec
ON u_exec.id = ut.exec_id
WHERE ut.state_key <> 'kClose'
";Значения в текст запроса не вклеиваются: в SQL стоит плейсхолдер
:ИМЯ в верхнем регистре, а значение кладётся в массив
параметров — подробнее в разделе «Работа с базой данных».
Все ключи шаблонизатора пишутся в верхнем регистре, слова разделяются знаком подчёркивания:
{TITLE}
{PAGE_NAME}
{PRODUCT:PRICE_OLD}
{#ITEMS}
<a href="?id={ID}">{NAME|html}</a>
{ITEMS#}