За основу для данного стандарта взята статья http://www.reg.ru/coding_standards.
Обязательна «лесенка» с отступом в 4 пробела (half-tab). При этом запрещается в редакторе изменять размер отображаемой табуляции, например выставлять отображение табуляции в 4 пробела. Код, созданный Вами при таких настройках, будет некорректно отображаться в других редакторах с другими настройками.
Величина отступа у двух соседних строчек, не должна превышать 4 пробела:
// Правильно
function get_id(
$name //!< Имя
) {
// Неправильно
function get_id(
$name //!< Имя
) {
После запятых и точек с запятой (если, конечно, они не расположены в конце строки) ставятся пробелы. Перед запятой и точкой с запятой пробелы не ставятся:
$a = array (1, 2, 3);
for ($i = 0; $i < $count; $i++) { };
Любые операторы / знаки операций (например =, ==, ⇒, <, >, &&, || и т.п.) обязательно отделяются пробелами с обоих сторон
В арифметических выражениях количество пробелов вокруг знаков операций можно варьировать, чтобы подчеркнуть приоритет операций. Примеры:
$a = $b * $c + $d * $e; $a = $b * $c + $d * $e;
В случае, если Вы обращаетесь к элементу массива по индексу и индексное выражение достаточно сложное, отделяйте его пробелами для улучшения удобочитаемости. Если выражение простое — пробелы не обязательны.
$a[1];
$a[ 1 + 2 + 2 + 4 * function( $a{ $b->{c} } ) ];
После символа начала комментария («») перед текстом самого комментария ставится пробел: <code> Комментарии начинаются С ЗАГЛАВНОЙ БУКВЫ! Вторая строка комментария </code> Исключение составляют fancy comments, где допускается сливать начальнуй символ решётки с последующими символами: <code> / MY COMMENT / INIT * </code>
После любых ключевых слов языка php обязательно следует пробел. Примеры:
$array = array ();
foreach ($array as $k => $item) {
if ($item) { $array[$k] = $item * 2; }
}
Для того, чтобы понять, насколько хорошо отформатирован Ваш исходный текст: достаточно ли отступов, пробелов и пустых строк — попробуйте отключить подсветку синтаксиса в Вашем редакторе. Если после отключения подсветки код по-прежнему легко читаем (просмотр и анализ текста производится легко, любые конструкции легко выделяются визуально) — значит код действительно удобочитаем.
Не стоит полагаться на подсветку синтаксиса как на «костыль», скрывающий недостатки форматирования.
Левый край комментариев выравнивается точно так же, как и основной код, т.е. используется принцип «лесенки».
//// тили-тили
//// трали-вали
if ($cond) {
/*
Это дело мне по силе,
Откажусь теперь едва ли.
*/
}
else {
# Это мы не проходили,
# Это нам не задавали!
}
Ставить символы «» вначале строки, если левая граница кода находится правее, не допускается. тили-тили
// трали-вали
if ($cond) {
// ТАК ДЕЛАТЬ НЕЛЬЗЯ!!!
}
Строки не оставлять слишком длинными; ограничение — 80 символов в строке. При необходимости строка разбивается на несколько. Примеры допустимого разбивания конструкций:
if (
very_long_condition_1
&& very_long_condition_2
) {
statement;
}
if (
..
&&
...
||
...
) {
...
}
Для контроля длины строк рекомендуется включить режим «статического переноса строк» после 80 символов. Большинство редакторов имеют эту возможность.
Старайтесь придерживаться компактного (K&R) стиля оформления циклов и блоков ветвления: открывающая фигурная скобка находится на той же строке, что и ключевое слово for, if, else, while и т.п. Закрывающая фигурная скобка блока, состоящего из нескольких строк, должна находиться на одной вертикали с ключевым словом начинающим конструкцию. Примеры:
if ($condition) {
statement1;
}
else {
statement2;
}
for ($i = 0; $i < $count; $i++) {
statement;
}
Перед открывающей фигурной скобкой в блочных конструкциях всегда ставится пробел:
foreach ($array as $item) {
statement;
}
Однострочные блоки, состоящие из единственного оператора, могут быть помещены в одну строку вместе с открывающими и закрывающими скобками:
foreach ($array as $item) { $item *= 2; }
Код внутри функций должен быть разделён на смысловые блоки, выполняющие определённую узкую задачу. Смысловые блоки отделяются друг от друга пустыми строками. Для дальнейшего улучшения сопровождабельности кода, добавляйте вначале каждого абзаца однострочный комментарий, объясняющий, что делает эта последовательность операторов.
Выравнивайте сходные элементы по вертикали, особенно если они достаточно короткие чтоб поместиться в одну строку:
$wm_conts_map = array (
first_name => 'iname',
last_name => 'fname',
email => 'email',
);
mkdir($tmpdir) or die ("can't mkdir $tmpdir");
chmod($tmpdir, 0777) or die ("can't change mode for $tmpdir");
Над константами обязательно необходимо ставить комментарий в формате doxygen
//! Режим отладки
define ("DEBUG_MODE", "1");
Важно ставить открывающую скобку слитно с именем функции или переменной. В противном случае можно визуально спутать функцию с ключевым словом, а начало выражения для элемента массива.
# ХОРОШО
if (open_region($i)) { next CANDIDATE; }
$candidates[$i] = $incumbent[ $candidates[$i]['region'] ];
# ПЛОХО!
if (open_region ($i)){ next CANDIDATE; }
$candidates[$i] = $incumbent [ $candidates[$i]['region'] ];
Индексы ассоциативных массивов должны представлять собой только текстовые значения (тип кавычек - не важен)
# ХОРОШО $array['type_id'] = 1; $array["type_id"] = 2; # ПЛОХО! $array[type_id] = 3;
Выбирайте осмысленные названия для идентификаторов (переменных, констант, функций). Исключение составляют итераторы циклов, где допускаются короткие идентификаторы: $i, $n и т.п. При этом не допускается калька с русского языка («$polzovatel», «$sajt» и т.п.). Если вы не можете вспомнить, что это имя значит — у вас проблемы.
Названия всех переменных и функций должны состоять только из строчных букв, цифр и знаков подчёркивания: «get_domain_name» и т.п.
Хотя короткие идентификаторы типа «$gotit» возможно и неплохи, используйте знак подчеркивания для разделения слов. В общем случае «$var_names_like_this» прочесть легче чем «$VarNamesLikeThis».
Константы именуются только с использованием заглавных букв:
define ("DEBUG", 0);
Массивы рекомендуется называть во множественном числе, например $users, $objects, а скаляры — в единственном: $user, $object.
Если функция выполняет несколько разных, слабо связанных друг с другом задач, подумайте о том, чтобы разбить эту функцию на несколько.
Наименования функций должны включать глагол, например «get_domain_name», или «chash_my_program».
Имена, заданные без учёта этого принципа, вроде «flat_components», могут быть истолкованны совершенно по разному, например как «get_flat_components», «set_flat_components», «update_flat_components», «remove_flat_components» или «add_flat_components»
В книге Стива Макконелла «Совершенный код» приводятся устоявшиеся пары антонимов, рекомендуемые для использования в именах функций/методов, а именно:
Использование «несогласованных» пар глаголов вроде add / delete или insert / destroy вводит в заблуждение и усложняет анализ кода.
Если в модуле присутствуют функции, предназначенные только для внутреннего использования, которые никогда не будут вызваны за пределами модуля (за исключением случая автоматического тестирования), можно предварять имена этих private-функций знаком подчёркивания. Пример: _do_some_private_actions.
Функции отделены друг от друга минимум одной пустой строкой. Для каждой функции необходимо краткое однострочное описание того, что она делает. Так же необходимо дать краткое описание входных параметров:
/**
Получить имя домена по его id (краткое однострочное описание)
Прочее описание
*/
function get_domain_name(
$id //!< id домена
) {
...
}
Подобный формат написания комментариев связан с последующей обработкой кода с помощью doxygen, для получения документации по исходникам.
Функция может принимать не более 2-х, максимум 3-х аргументов. При большем количестве аргументов либо проводится рефакторинг с целью уменьшения количества входных параметров, либо используются именованные параметры. Именованные параметры обязательно документируются
Если выходные параметры функции не очевидны / нетривиальны, особенно это касается возврата сложных структур данных, их обязательно надо документировать
Вначале библиотеки обязателен комментарий, описывающий её назначение.
/** Краткое описание библиотеки
\author Пупкин Василий
Подробное описание
*/
Вначале класса обязателен комментарий, описывающий её назначение.
/**
Краткое описание класса
*/
class myclass {
...
}
Файлы библиотек следует называть в стиле mylib.lib.php. В то время как исполняемые файлы («скрипты»), следует именовать маленькими буквами, с применением знака подчёркивания: clear_cache.php.
Если требуется использовать «тяжёлую» библиотеку (скажем, отъедающую 5 Мб памяти и более), при этом, необходимость в этой библиотеке возникает лишь изредка, при определённых условиях — лучше её динамически, когда в нём возникает необходимость:
define ("", $_SERVER['DOCUMENT_ROOT']);
$include_file = DOCUMENT_ROOT."/libs/mylib.lib.php";
if ($condition) {
if (file_exists($include_file)) {
include_once($include_file);
}
}
Для указания пути к библиотеки обязательно использовать полный путь в файловой системе. Его можно получить из переменной окружения $_SERVER[’DOCUMENT_ROOT’], либо указав его в константе.
define ("", $_SERVER['DOCUMENT_ROOT']);
$include_file = DOCUMENT_ROOT."/libs/mylib.lib.php";
if ($condition) {
if (file_exists($include_file)) {
include_once($include_file);
}
}
Выбирайте осмысленные названия для полей и таблиц. При этом не допускается калька с русского языка (‘polzovatel‘, ‘sajt‘ и т.п.). Если вы не можете вспомнить, что это имя значит — у вас проблемы.
Имена таблиц, полей и их псевдонимов обязательно заключаются в обратные апострофы (символ ‘).
Запросы длиной более 50 символов (примерно) рекомендуется разбивать на несколько строк, подгоняя текст по горизонтали. Например так:
SELECT `fields`
FROM `tables` `t`
WHERE conditions
AND more conditions
GROUP BY `fields`
ORDER BY `fields`
LIMIT limits
или так:
SELECT
`fields`
FROM
`tables` `t`
WHERE
conditions
AND
more conditions
GROUP BY
`fields`
ORDER BY
`fields`
LIMIT
limits
Все ключевые слова SQL записываются заглавными буквами, все наименование таблиц, полей, пользовательских функций — строчными.
При именовании таблиц и полей не допускается использование заглавных букв. Допускаются только строчные латинские буквы, цифры и знак подчёркивания. Пример: «name_of_the_table».
Таблицы следует именовать по-английски, во множественном числе. Например: «domains», «users».
В каждой таблице (за исключением таблиц, где необходимы составные ключи, например таблиц для обеспечения связей многие-ко-многим) обязательно должно быть поле с именем «id» и типом INT, для которого должен быть создан первичный ключ:
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
Поле для первичного ключа может быть названо по другому и иметь другой тип, но это обязательно обсуждается с другими членами команды и выносится соответствующее обоснование.
Все поля, использующиеся для связи с другими таблицами по их первичному ключу, именуются как »<tablename>_id», где »<tablename>» — имя таблицы в единственном числе. Примеры наименований: domain_id, user_id.
Кодировка комментариев на русском языке должна быть ЕДИНОЙ на протяжении всего проекта (в зависимости от принятых для этого проекта договорённостей).
Перед телом функции обязательно ставится краткое описание того, что она делает. Назначение входных параметров так же комментируется:
/**
Краткое описание функции
Полное описание функции
*/
function my_func(
$xml, //!< Описание аргумента 1
$xsl_file //!< Описание аргумента 2
) {
....
}
Краткое описание является обязательным. Полное, если работа функции сложна и нетривиально. Так же не стоит забывать о допустимом предельном количестве аргументов
Перед телом цикла обязательно должен стоять комментарий, кратко описывающий работу цикла
// Описание рабты цикла
foreach () {
...
}
Перед условием обязательно должен стоять комментарий, кратко описывающий его работу
// Описание условия
if () {
...
}
Экранирование поставляемых данных во избежание XSS-атак При подстановке в шаблон данных, передаваемых пользователем (например, переданных ранее через форму на сайте), эти данные обязательно экранируются с помощью фильтра html (за исключением ОСОБЫХ случаев):
<?= htmlspecialchars($form_data);?>
К оформлению кода внутри шаблонов применяются те же самые требования, что и к оформлению кода на PHP. В частности это касается расстановки пробелов (пробелы вокруг операторов, пробелы после запятых, вокруг сложных индексных выражений и т.п.).
При использовании логических / блочных конструкций TT данные, внутри блока сдвигаются вправо для улучшения удобочитаемости
{if $ru}
Русский текст
{else}
Английский текст
{/if}
В случае необходимости отображения списка или таблицы, где строки передаются в виде массива, должна быть проверка на непустоту этого массива и соответствующая адекватная реакция. Например, вместо вывода пустой таблицы или списка лучше вывести пояснительный текст: «Заказы пока отсутствуют» или «Новостей на сегодня нет».
Шаблон должен интерпретироваться без ошибок даже в случае, если требуемые шаблоном переменные не передаются шаблонизатору. Это означает, что в шаблонах должна быть предусмотрена адекватная защита, на случае, если данные не передаются.
Не использовать знаки номера, копирайта, спец-кавычек и т.п., записанные в виде символов в национальной кодировке, скажем cp1251. Далеко не во всех редакторах и операционных системах Ваши символы будут корректно отображаться.
Для каждого элемента <input type=«checkbox» …> должен быть предусмотрен элемент <label>, для того, чтобы чекбокс срабатывал также по клику по метке:
<label><input type="checkbox" name="test" value="1">Тестовая метка</label>
Textarea в форме минимум на 10 строк высоты (очень неудобно постоянно делают 4-6 строк)
Возможно следует задать минимум в см.
Использование в форме тегов th для заголовков полей и тегов td содержащих поля. При этом чекбоксы с их лэйблами хранятся в тэгах td аналогично input.
<form>
<table>
<tr>
<th>Field1:</th>
<td><input ...></td>
</tr>
</table>
</form>
Всегда объявляйте переменные в JavaScript, даже если синтаксис языка допускает использование переменной без её объявления. Не позволяйте себе «расслабиться»!
var variable = 'Value';
alert( variable );