Правила и рекомендации по именованию

Содержание...

Внутренняя логика фреймворка опирается на ряд соглашений об именовании (файлов, классов, таблиц), несоблюдение которых приведет к неработоспособности приложения, поэтому соблюдение правил именования является одним из краеугольных камней при разработке приложений Вебасист и является обязательным.

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

База данных #

Таблицы

Обязательное правило: названия всех таблиц приложения должны начинаться с идентификатора приложения (APP_ID), отделенного символом подчеркивания.

Рекомендация: таблицы сущностей, например, для хранения сообщений в гостевой книге, стикеров, файлов и т.д., рекомендуется называть в единственном числе.

Примеры:

Рекомендация: таблицы связей, а так же таблицы, хранящие дополнительные данные, рекомендуется именовать по следующему правилу:
Название таблицы формируется из двух слов (в дополнение к обязательному префиксу APP_ID), разделенных символом подчеркивания - название главной сущности в единственном числе плюс второстепенная сущность во множественном числе (при наличии такой формы в названии сущности).

Примеры:

Таблица для хранения email-ов контактов.
wa_contact_emails — связь один ко многим, один контакт — несколько email

Таблицы плагинов

Обязательное правило: названия всех таблиц плагина должны формироваться по шаблону вида app_plugin_name, где вместо app и plugin следует использовать идентификаторы приложения и плагина, а вместо name — произвольное имя таблицы.

Поля

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

Примеры:

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

Рекомендация: поля внешних ключей рекомендуется именовать следующим образом: название таблицы (без префикса) на которую ссылается поле, далее название соответствующего поля в этой таблице.

Примеры:

Там где это необходимо, и для большей понятности, можно добавлять к такому имени поля смысловой префикс.

Например:

Классы, методы и переменные PHP #

Наименование классов и методов

Обязательное правило: названия всех классов приложения должны начинаться с идентификатора приложения (APP_ID). Это необходимо, чтобы не возникало конфликтов имён между классами разных приложений.

Обязательное правило: для именования классов и методов необходимо использовать так называемый «горбатый стиль»:
Слова в названии пишутся слитно (без символа-разделителя), первое слово (для классов - APP_ID) с маленькой буквы, остальные с большой.

Пример:

<?php

class filesFile
{

    public function getInfo() 
    {
        ...
    }
    ...
}

Именование PHP-файлов классов

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

Обязательное правило: все файлы классов должны находиться внутри подпапки lib в каталоге приложения.

Обязательное правило: название файла класса должно иметь следующий формат: {НАЗВАНИЕ_КЛАССА}.class.php. Например, если класс называется contactsCollection, то его файл должен называться contactsCollection.class.php.

Обязательное правило: для файлов экшенов, контроллеров и моделей существует дополнительный формат именования, который рекоммендуется использовать: если в названии класса содержится суффикс Actions, Action, Controller или Model, то название файла класса должно иметь следующий формат: {НАЗВАНИЕ_КЛАССА_БЕЗ_СУФФИКСА}.{суффикс}.php ({суффикс} пишется строчными буквами). Несколько примеров:

Именование классов и методов контроллеров и экшенов #

Логика приложения, живущая в слое контроллеров, организована в двухуровневую иерархию «модуль/действие» (MODULE/ACTION). Правила маршрутизации задают соответствие между URL запроса и парой модуль+действие. Т.е. каждый запрос по сути запускает выполнение определенного действия внутри определенного модуля.

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

Обязательное правило: название класса и метода для обработки запроса должны соответствовать правилам, по которым система ищет класс и метод для исполнения. Поиск производится в следующем порядке (конкатенация строк при построении названия класса производится в «горбатом» стиле без разделителей):

  1. Первым ищется класс с названием {APP_ID}{MODULE}{ACTION}Controller или, если не был указан ACTION, {APP_ID}{MODULE}Controller.
    Если такой класс найден, то создается экземпляр этого класса и вызывается его метод execute, то есть это "стартовая точка" контроллера этой страницы.

  2. Если класс найден не был, то ищется класс с названием, построенным по другому правилу - {APP_ID}{MODULE}Actions.
    Если такой класс найден, то создается новый экземпляр и вызывается метод {ACTION}Action, либо метод DefaulAction, если ACTION не был указан.
    Подобные контроллеры, методы которых - это отдельные экшены, популярны во многих фреймворках.

  3. Если второй вариант класса также не был найден, ищется третий вариант с названием {APP_ID}{MODULE}{ACTION}Action или, если не указан ACTION, {APP_ID}{MODULE}Action.
    Если такой класс найден, то создается его экзепляр и вызывается метод execute.

  4. Если ни один класс не найден, то отдается ошибка 404.

Примеры допустимых соответствий пар модуль + действие и названий классов и методов.

Приложение myblog, модуль mail, действие не указано:

  1. myblogMailController->execute()
  2. myblogMailActions->defaultAction()
  3. myblogMailAction->execute()

Приложение myblog, модуль mail, действие test:

  1. myblogMailTestController->execute()
  2. myblogMailActions->testAction()
  3. myblogMailTestAction->execute()

Подробнее система маршрутизации рассматривается в разделах «Маршрутизация в бекенд» и «Маршрутизация во фронтенд».

Именование файлов шаблонов #

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

Обязательное правило: файл шаблона ищется по следующему пути внутри файловой структуры приложения: templates/actions/{MODULE}/{MODULE}{ACTION}.html. Например, для модуля mail и действия test система применит в качестве шаблона файл templates/actions/mail/mailTest.html

Обязательное правило: для случаев, когда ACTION не был указан, правила именования шаблона зависят от типа класса экшена:

Подробнее о типах классов экшенов см. раздел «Экшены и контроллеры».

Именование глобально доступных идентификаторов (JavaScript, CSS, сессии, cookie) #

Глобально доступные идентификаторы (переменные и функции JavaScript, CSS-классы, параметры запросов, обрабатываемые классом waRequest, переменные пользовательских сессий и cookie) нужно именовать таким образом, чтобы они не приводили к конфликтам с любыми другими программными продуктами, которые могут использоваться в бекенде и фронтенде Вебасиста. Для этого в именах таких идентификаторов используйте ID вашего плагина или приложения.

Примеры

//JavaScript
var myplugin_var; //если нет другой возможности, добавьте ID плагина в имя глобальной переменной
//но лучше оформить такой JavaScript-код с использованием замыканий, как показано ниже

//CSS
.myplugin-settings .fields .field .name //например, оберните поля настроек в элемент с собственным CSS-классом и переопределяйте стили полей с использованием префикса
    
//PHP-сессии
wa()->getStorage()->set('shop_myplugin_custom_var', $data);
    
//Параметры запросов
waRequest::setParam('myplugin_custom_param', $data);

Рекомендация: при написании JavaScript-кода желательно не использовать глобальные идентификаторы и оформлять код плагина с использованием замыканий.

Пример

//Нежелательно
var myplugin_global_var = '...'; //пусть и с собственным префиксом, эта переменная будет доступна в коде других плагинов и самого приложения
if (myplugin_global_var) {
    ...
}

//Лучше
(function () {
    var global_var = '...'; //эта переменная доступна только в коде плагина и с другими плагинами конфликтовать не будет
    if (global_var) {
        ...
    }
})();

Рекомендации по стилю форматирования PHP-кода #

Рекомендация: при разработке приложений (особенно при командной разработке), рекомендуется придерживаться единого стиля форматирования кода. Мы рекомендуем придерживаться стиля, применяемого в коде фреймворка и приложений Вебасист:

<?php //использовать только такой открывающий тег и никакой другой

/**
* @desc Всегда оставлять комментарии к своим классам в формате PhpDOC
*/
class CodingStyle //классы называть по правилу «верблюжьего горба»
{
  
  	//открывающую фигурную скобку в начале класса ставить с НОВОЙ строки

    //табуляция заменяется 4 пробелами
    //кодировка - UTF-8
    //переносы строк UNIX, то есть \n, а не \r\n

    /**
    * @desc формат названий переменных должен отличаться от формата названий методов
    * в названиях переменных использовать только маленькие буквы и разделять слова подчеркиванием
    */
    public $is_right;

    /**
    * @desc К методам и функциям писать комментарии
    * @param $code int - описывать входные данные
    * @return boolean - описывать выходные данные
    */
    public function doIWriteValidCode($code) //методы называть по принципу «верблюжьего горба»
    { //открывающую фигурную скобку в начале метода ставить с НОВОЙ строки

        //внутри методов и функций писать комментарии ТОЛЬКО в таком виде и не использовать
        //многострочное оформление даже если комментарии на несколько строк

        $this->is_right = false; //символы +-=*/{} и пр. обязательно отделять пробелами


        if (! $code) { //любую открывающую скобку внутри методов ставить на ТОЙ ЖЕ строке
            //нет кода - нет проблемы.
            $this->is_right = true; //использовать скобки, ДАЖЕ если оператор в конструкции один
        } else { //else/elseif писать на ТОЙ ЖЕ строке, что и закрывающая скобка оператора if
            $this->is_right = $this->checkMyCode($code);
        }

        return $this->is_right;
    }

    /**
    * @desc Составлять описание, даже если название метода говорит само за себя
    */
    public function checkMyCode($code)
    {
        return false; //Закон природы - мы всегда найдем к чему придраться, какой бы код ни был
    }
}

//в конце файла закрывающий тег не ставить