2. Руководство разработчика › 2.2 Устройство проекта › Принятые обозначения

Для облегчения восприятия кода и совместимости модулей разных разработчиков мы настоятельно рекомендуем придерживаться следующих соглашений об именовании.

Имена файлов

Корневые скрипты и HTML-шаблоны — нижний регистр, слова разделяются знаком подчёркивания:

index.php
page_catalog.php
main.htm
page_404.htm
item_product.htm

Модульные скрипты строятся по схеме из трёх частей, разделённых подчёркиванием:

{компания}_{группа}_{назначение}.php

Примеры:

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 модуля стоит в первой группе. Небольшому разделу группы не нужны: функции идут прямо под ним.

// ————— 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

Заголовки этапов ставятся в длинной функции, где этапов не меньше трёх; короткой функции они не нужны. Заголовок — не длиннее пяти слов: панель дерева узкая и обрезает длинные.

Переменные в PHP-скриптах

Тип переменной Правило Пример
Входные параметры функции Начинаются с $m, далее camelCase $mVars, $mTopicId, $mTpl
Локальные переменные Нижний регистр, слова через _ $id, $item_count, $command
PHP-константы Верхний регистр, слова через _ MELBIS_CACHE, MELBIS_LANG

В главной функции модуля массив входных параметров принято называть $mVars.

Псевдонимы таблиц в SQL

Псевдоним таблицы — аббревиатура из первых букв слов её имени (префикс {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 стоит плейсхолдер :ИМЯ в верхнем регистре, а значение кладётся в массив параметров — подробнее в разделе «Работа с базой данных».

Ключи в HTML-шаблонах

Все ключи шаблонизатора пишутся в верхнем регистре, слова разделяются знаком подчёркивания:

{TITLE}
{PAGE_NAME}
{PRODUCT:PRICE_OLD}
{#ITEMS}
    <a href="?id={ID}">{NAME|html}</a>
{ITEMS#}