Стандарт написания кода
В рамках VQS необходимо придерживаться следующих правил.
1. Форматирование PHP-файлов
Рекомендуемая длина строки составляет 80 символов, т.е. разработчики должны стремиться держать код как можно ближе к 80-символьной границе, когда это возможно. Однако более длинные строки также допустимы. Максимальная длина любой строки PHP-кода не должна превышать 120 символов.
1.1. Отступы
Использовать tab вместо пробелов, т.к. обычно редактор настраивается, сколько пробелов проставлять за tab. Настроить на 4 пробела.
Делаем отступов столько, сколько необходимо, но не больше. Существует правило о максимуме числа отступов. Если вложенность в коде больше, чем 4 или 5 уровней, то следует задуматься о переработке такого кода.
2. Соглашения по именованию
Хорошее именование в коде имеет определяющее значение при отладке, поиске ошибок и дальнейшей работе с кодом.
2.1. Имена файлов
Для файлов допустимы буквенно-числовые символы (нижнего регистра), символы нижнего подчеркивания и тире («-»). Пробелы запрещены. Необходимость верхнего регистра обсуждается в частных случаях.
Если файл содержит любой php-код, то он должен заканчиваться «.php»
2.2. Именование функций и методов
Имена функций могут содержать буквенно-числовые символы. Символы нижнего подчеркивания крайне не желательны. Числа разрешены в именах функций, но не приветствуются (исключение – числа, заменяющий слова – 4=for; 2=to).
Имена функций должны всегда начинаться с буквы в верхнем регистре. Когда имя функции состоит из более, чем одного слова, первая буква каждого нового слова должна быть заглавной. Это обычно называется «верблюжьей» («СamelCase») нотацией. Обычно, метод или функция выполняют какое-либо действие, поэтому имя такого метода или функции должно указывать на это действие: CheckForErrors() вместо ErrorCheck(), DumpDataToFile() вместо DataFile().
Многословность приветствуется. Имена функций должны быть настолько говорящими, насколько это практично для повышения понимаемости кода.
Если необходимо в функции что-то выяснить, то удачно дать ей имя с префиксом Is. Напр. IsAuthorized()
Принято, чтобы методы доступа имели префикс «Get» или «Set» (если необходимо что-либо вернуть, либо установить)
2.3. Именование переменных
Имена переменных могут содержать буквенно-числовые символы. Символы нижнего подчеркивания не разрешены. Числа разрешены в именах переменных, но не приветствуются
Как и имена функций (смотрите выше) имена переменных должны начинаться с буквы в нижнем регистре и следовать «верблюжьей» нотации.
Многословность приветствуется. Имена переменных должны быть настолько говорящими, насколько это практично. Краткие имена переменных, такие как «$i» и «$n» не приветствуются нигде, кроме как в контексте маленьких циклов. Если цикл содержит более 20 строк кода, то переменные для индексов должны иметь более говорящие имена.
Имена переменных, содержащие только нижний регистр и знак подчеркивания, разрешается использовать только в локальных частях кода, содержащего не более 20 строк. В противном случае переменной необходимо давать осмысленное название.
Встроенные переменные PHP true, false и null должны быть написаны в нижнем регистре.
Использование говорящих префиксов/суффиксов — это хорошо: Например, Max — обозначает, что переменная хранит какой-либо максимум, Cnt, Count – обозначает, что переменная хранит кол-во чего-либо. Например: $itemsMax — максимальное значение в массиве; $dateOfSomething – дата какого-либо события; $useHtml, $isHtml — для флагов.
2.4. Константы
Константы могут содержать буквенно-числовые символы и символы нижнего подчеркивания. Числа разрешены в именах констант.
Имена констант должны быть в верхнем регистре.
Имена констант из нескольких слов пишутся, разделяя каждое слово знаком подчеркивания (напр. EMBED_SURPRESS)
3. Стиль кодирования
3.1. Строковые литералы
Когда строка является литеральной (не содержит подстановок переменных), для ее обрамления должны использоваться апострофы или «одинарные кавычки» ($a = 'Example String';)
Когда строка литералов сама содержит апострофы, разрешается для обрамления строки использовать «двойные кавычки». Это особенно актуально для SQL-запросов:
$sql = «SELECT `id`, `name` from `people` WHERE `name`='Fred' OR `name`='Susan'";
3.2. Конкатенация строк
Строки должны объединятся с помощью оператора «.». Пробел должен всегда добавляться до и после оператора «.» для улучшения читабельности: ($company = 'Zend' . 'Technologies';)
Когда производится конкатенация строк с помощью оператора «.», разрешается разрывать выражение на несколько строк для улучшения читабельности. В этом случае, каждая следующая строка должна быть дополнена пробелами так, чтобы оператор «.» был выровнен под оператором «=» или «.
3.3. Массивы с числовыми индексами
Хотя индекс массива может начинаться с отрицательного числа, но это не приветствуется и рекомендуется, чтобы все массивы начинали индексирование с 0.
Когда определяется индексированный массив с помощью конструкции array, завершающий пробел должен быть добавлен после каждой запятой для улучшения читабельности: $sampleArray = array(1, 2, 3, 'Zend', 'Studio');
Также разрешается определять многострочные индексированные массивы, используя конструкцию «array». В этом случае, каждая следующая строка должна быть дополнена пробелами так, чтобы начало каждой строки было выравнено.
3.4. Ассоциативные массивы
Когда определяется ассоциативный массив с помощью конструкции «array», приветствуется разделение выражения на несколько строк. В этом случае, каждая следующая строка должна быть дополнена с помощью пробелов так, чтобы и ключи и значения были выровнены.
<?php
$sampleArray = array(
'firstKey' => 'firstValue',
'secondKey' => 'secondValue'
);
?>
3.5. Использование функций и методов
Функции должны определяться по следующей схеме:
- аргументы функции разделяются одним завершающим пробелом после каждой запятой.
- вызовы функций должны быть написаны без отступов между именем функции, открывающей скобкой и первым параметром. Отступы в виде пробела должны присутствовать после каждой запятой в перечислении параметров ($var = foo($bar, $baz, $quux);)
3.6. Управляющие структуры и простановка скобок
Управляющие структуры включают в себя операторы if, for, while, switch, и др. Ниже приведен пример оформления оператора if, который в этом отношении является самым сложным. Его и рассмотрим, другие пишутся по аналогии. Этот стиль называется «trailing braces», его использовать во всех управляющих конструкциях. Стиль «one true brace» (каждая скобка на новой строке) остается в черном списке, хотя и может встречаться в коде.
Управляющие структуры, основанные на конструкциях if и elseif, должны иметь один пробел до открывающей круглой скобки условия, и один пробел после закрывающей круглой скобки.
Внутри выражения условия между круглыми скобками операторы должны разделяться пробелами для читабельности. Внутренние скобки приветствуются для улучшения логической группировки больших условий.
Открывающаяся фигурная скобка пишется на той же строке, что и условие. Закрывающаяся фигурная скобка пишется на отдельной строке. Все содержимое между скобками пишется с отступом в 4 пробела (или один tab).
<?php
if ($a != 2) {
$a = 2;
}
?>
Для выражения if, включая elseif или else, форматирование должно быть таким, как в следующем примере:
<?php
if ($a != 2) {
$a = 2;
} else {
$a = 7;
}
?>
Ключевые слова должны быть строго в нижнем регистре: array, if, foreach, while, true, false, null, new, class, function, ...
PHP допускает написание таких выражений без фигурных скобок при некоторых условиях. Поэтому в ряде случаев допустимо оформлять код без использования фигурных скобок.
<?php
if ($a != 2)
$a = 2;
else
$a = 7;
?>
Использование комбинации «else if» вместо конструкции elseif допускается.
Альтернативный синтаксис рекомендуется использовать только в частях, которые используют прерывания на вывод html-кусков (напр. для шаблонов вывода). Просто в отформатированном PHP-коде строго не рекомендуется использовать альтернативный синтаксис, т.к. теряется учет открытых-закрытых скобок (к тому же многие среды разработки позволяют легко найти открывающуюся скобку по закрытой, но не позволяют найти начало if (…): по его окончанию — endif;).
3.7. Правила написания switch-конструкции
Управляющие структуры написанные с использованием «switch» конструкции должны иметь один пробел до открывающей круглой скобки условного выражения, и также один пробел после закрывающей круглой скобки.
Все содержимое между фигурными скобками пишется с отступом. Содержимое каждого «case» выражения также должно писаться с отступом
Ключевое слово default никогда не должно опускаться в выражении switch.
ЗАМЕЧАНИЕ: Иногда полезно писать case-выражения, которые передают управление следующему case-выражению, опуская break или return. Для того, чтобы отличать такие случаи от ошибок, каждое case-выражение, где опущен break или return, должно содержать комментарий.
3.8. Тернарный оператор ’?:’
Проблема обычно заключается в том, что люди пытаются запихать слишком много кода между ?" и :«. Вот несколько правил:
- условие заключайте в скобки, тем самым отделяя его от остального кода
- по возможности действия, производимые по условию, должны быть простыми функциями
- если весь блок ветвления плохо читается, будучи расположен на одной строке, то блоки else размещайте каждый на отдельной строке
3.9. Использование коротких тегов ’<?’ и ’<?=’
Использование коротких тегов разрешается, если такое поведение разрешено директивой short_open_tag конфигурационного файла php.ini. Для вывода в шаблоне одной переменной или результата выражения «?:» удобно пользоваться записью ’<?=’ вместо ’<?php echo’. Для длинных выражений (более одного тернарного оператора) использование такой записи практически не оправдано.
3.10. Пробелы вокруг знаков операций
Любые операторы / знаки операций (например =, ==, =>, >, <, &&, || и т.п.) обязательно отделяются пробелами с обоих сторон. В арифметических выражениях количество пробелов вокруг знаков операций можно варьировать, чтобы подчеркнуть приоритет операций.
Примеры:
$a = $b * $c + $d * $e;
$a = $b * $c + $d * $e;
Для читаемости уместно поставить скобки, хотя тут они и не требуются
$a = ($b * $c) + ($d * $e);
3.11. Пробелы вокруг сложных индексных выражений
В случае, если Вы обращаетесь к элементу массива по индексу и индексное выражение достаточно сложное, отделяйте его пробелами для улучшения удобочитаемости. Если выражение простое — пробелы не обязательны.
$arTmp['KEY'] = 0;
$arItems[$formId][ $arPage["VALUE"] * 2 – 4 ] = $arTmp;
3.12. Каждый оператор должен быть на новой строке
Необходимо, чтобы в каждой строчке присутствовало только одно выражение.
3.13. Пустые строки для дробления кода на логические блоки
Пустые строки помогаю разбивать код приложения на логические сегменты. Несколькими строками могут отделяться секции в исходном файле. Одной пустой строкой отделяются друг от друга методы, логические секции внутри метода для более удобного чтения.
4. Дополнительные частные случаи, на которые следует обратить внимание
4.1. Короткие методы
Желательно, чтобы метод (функция) занимал не более одной страницы кода. Большой метод необходимо делить на кучу маленьких, в таком случае мы добиваемся преждевременной оптимизации кода за счет продумывания структуры одной большой задачи и разделение их на подзадачи (структурный подход к построению решения)
4.2. Рефакторинг
Если код Вам перестаёт нравится: функция слишком сложная и длинная (более 100 строк), слишком много входных и выходных параметров, неудачное название функции и т.п. — делайте рефакторинг. После проведения рефакторинга обязательно запускайте автоматические тесты. Если для функции, над которой Вы работали, тесты не предусмотрены — создайте их.
4.3. Не живите с «разбитыми окнами»!
Не оставляйте «разбитые окна» (неудачные конструкции, неверные решения или некачественный текст программы) без внимания. Как только Вы их обнаружите — чините сразу. Часто безошибочные, функциональные системы быстро портились, как только окна начали разбиваться. Не давайте энтропии победить себя.
4.4. Старайтесь повторно использовать свой и чужой труд
Очень часто разработчики ленятся делать библиотеки классов & методов, которые упрощают жизнь и себе и команде. Очень хорошо, когда программист собирает себе библиотеку с кодом для последующего использования.
4.4.1. Do not Repeat Youself — не повторяй самого себя!
Подумайте о повторном использовании кода. Зачем тратить впустую усилия мысли на одноразовые программы, если в будущем вам может потребоваться что-то подобное снова? Подумайте над обобщением вашего кода. Подумайте над написанием модуля или класса. Подумайте, не предложить ли Ваш код другим.
4.4.2. Don’t Reinvent Wheel — Не переизобретайте колесо!
Не переизобретайте колесо — если подобное колесо уже существует, просто адаптируйте его для своих нужд. Вероятно, для решения данной проблемы уже существует стандартный модуль в ядре PHP или API CMS, или модуль, разработанный другими людьми внутри организации. Иногда не составляет труда найти нужный код в интернете.
4.5. Куски кода и ответственность
Каждый человек должен отвечать за свои куски кода. Соответственно, если в них возникают ошибки, то человек, который написал код, идет исправлять ошибку. Тем более если из-за части чьего-то кода перестает работать вся целая система, то за эту часть «создатель» должен нести ответственность.