Стандарты кодирования PSR-0, PSR-1, PSR-2, PSR-3, PSR-4, PSR-7. Часть первая, для учеников первого уровня.
Притча: жили-были поживали программисты и бед не знали. Однажды они заглянули в код своих коллег и ужаснулись, ведь один написал CLASSNAME, второй Classname, третий ClassName, а четвертый вообще добавил нижнее подчёркивание. Какой бардак сказал самый умный из них. А давайте мы объединимся и попробуем составить некий единый стандарт, чтобы все им пользовались. И нам удобно, и нашим коллегам, и новичкам, которые будут так же работать в нашей команде. Решили они и сделали и так появился первый стандарт под названием PSR-0. Потом они почесали бороды (те, у кого не было своих бород - чесали бороды своих коллег), и расширили стандарты, так и повелось. И теперь, каждый цикл специальная группа людей, входящие в разработки современных FrameWork и СMS обсуждают и дорабатывают эти правила.
Жили и будут прекрасно поживать бравые молодцы из команд: Zend Framework 2, Yii framework, Wikibase, Symfony, PrestaShop, PHPixie, phpBB, CakePHP, Composer, Doctrine, Drupal, Joomla, Laravel, PEAR и других менее известных мне, но не менее прекрасных..
А ты, мой юный читатель, сейчас насладишься собранием стандартов PSR-1, PSR-2, PSR-3, PSR-4, PSR-7, которые являются официальными и действующими на сегодняшний день. А если выйдет новый стандарт, то всегда можно отправить мне почтового голубя с напоминанием, или постучаться в скайп.
Стандарт PSR-1. Основной стандарт кодирования
1) В файлах НЕОБХОДИМО использовать только теги Ссылка на документацию.
2) В файлах с кодом PHP НЕОБХОДИМО использовать только UTF-8 без BOM.
3) В одном файле СЛЕДУЕТ либо объявлять символы (классы, функции, константы и т. д.), либо выполнять побочные действия (т. е. производить вывод, менять значения .ini и т. д.), но НЕ СЛЕДУЕТ делать и то и другое одновременно. В данном случае подразумевается, что функции/классы должны идти отдельно от контроллеров и моделей. Неправильно было бы писать так:
<?php
// побочное действие: установка уровня ошибок
error_reporting(-1);
// побочное действие: подключение файла
include 'config.php';
// побочное действие: генерация вывода текста
echo 'Тут меню';
// объявление (ПРАВИЛЬНАЯ ЧАСТЬ)
function bar() {
// тело функции
}
4) Классам НЕОБХОДИМО давать имена в стиле StudlyCaps (название записанное без пробелов + каждое слово в этом названии начинается с большой буквы).
5) Константам классов НЕОБХОДИМО давать имена в верхнем регистре с символом подчёркивания в качестве разделителя: MAIN_PRODUCT.
6) Методам НЕОБХОДИМО давать имена в стиле camelCase (верблюжий стиль. Название записывается без пробелов, каждое слово с большой буквы, кроме первого). Свойства классов можно писать способами StudlyCaps, camelCase, или через нижнее подчеркивание $main_product.
PSR-2. Стиль кодирования
1) Для отступов необходимо использовать 4 пробела, а не табуляцию. (Я с этим немного не согласен, так как табуляция значительно удобнее в плане работы с ней, но всегда можно настроить IDE так, чтобы он сохранял файл с автозаменой табуляции на 4 пробела. Путаница возникает только тогда, когда человек ставит 1 пробел, а потом нажимает табуляцию. Некоторые IDE приводят к виду в 4 пробела, а некоторые к 5-и пробелам, особенно заметно в исходном коде Google Chrome. Отсюда и рекомендуют ТОЛЬКО пробелы ставить. В свою очередь можно настроить IDE так, что по нажатию TAB ставились 4 пробела, а не табуляция. Для этого в PHPStorm перейдите в Settings - Editor - Code Style - PHP, и снимите галочку с Use tab character).
2) Нельзя жёстко ограничивать длину строки, но мягкое ограничение длины строки должно быть 120 символов; строки желательно делать не длиннее 80 символов. Под жёсткого ограничения подразумевается то, что если у Вас возникла строка в 81 символ, то не надо этот 1 символ переносить на новую строчку.
5) После ключевых слов управляющих структур НЕОБХОДИМО ставить один пробел; после названий функций и методов — НЕДОПУСТИМО. Открывающие фигурные скобки управляющих структур НЕОБХОДИМО оставлять на той же строке, а закрывающие фигурные скобки переносить на следующую строку после тела. НЕДОПУСТИМО ставить пробел после открывающих круглых скобок управляющих структур и НЕДОПУСТИМО ставить пробел перед закрывающими круглыми скобками управляющих структур.
if ($x == 1) {
test();
} elseif () {
test2();
}
Список аргументов функции МОЖНО разбить на несколько строк, каждая из которых с одним отступом. При этом первый аргумент в списке НЕОБХОДИМО перенести на следующую строку, и в каждой строке НЕОБХОДИМО указать только один аргумент.
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
7) Все PHP-файлы НЕОБХОДИМО заканчивать одной пустой строкой.
8) В конце файла не закрывать PHP ?> Ссылка на документацию
9) Ключевые слова необходимо писать в нижнем регистре. Константы true, false, null так же в нижнем регистре. Список ключевых слов.
10) if, elseif, else
<?php
if ($expr1) {
// тело if
} elseif ($expr2) {
// тело elseif
} else {
// тело else;
}
11) switch, case
<?php
switch ($expr) {
case 0:
echo 'Первый case, заканчивается на break';
break;
case 1:
echo 'Второй case, с умышленным проваливанием';
// no break
case 2:
case 3:
case 4:
echo 'Третий case, завершается словом return вместо break';
return;
default:
echo 'По умолчанию';
break;
}
12) while, do-while, for, foreach
<?php
while ($expr) {
// structure body
}
do {
// structure body;
} while ($expr);
for ($i = 0; $i < 10; $i++) {
// тело for
}
foreach ($iterable as $key => $value) {
// тело foreach
}
13) try, catch
try {
// тело try
} catch (FirstExceptionType $e) {
// тело catch
} catch (OtherExceptionType $e) {
// catch body
}
Классы
1) Открывающие фигурные скобки классов НЕОБХОДИМО переносить на следующую строку, а закрывающие фигурные скобки переносить на следующую строку после тела.
class Core
{
public function test
{
//тут код
}
}
2) Видимость НЕОБХОДИМО объявлять для всех свойств и методов (public, private...)
3) НЕОБХОДИМО оставлять одну пустую строку после объявления пространства имён (namespace) и НЕОБХОДИМО оставлять одну пустую строку после блока операторов use.
<?php
namespace Vendor\Package;
use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class Foo extends Bar implements FooInterface
{
public function sampleFunction($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// тело метода
}
}
4) Ключевые слова extends и implements НЕОБХОДИМО располагать на одной строке с именем класса. Список implements МОЖНО разбить на несколько строк, каждая из которых с одним отступом. При этом первый интерфейс в списке НЕОБХОДИМО перенести на следующую строку, и в каждой строке НЕОБХОДИМО указать только один интерфейс.
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// константы, свойства, методы
}
5) НЕ СЛЕДУЕТ начинать название метода или свойства с подчёркивания для обозначения приватной или защищённой видимости.
6) НЕДОПУСТИМО в одном объявлении видимости указывать более одного свойства.
7) НЕДОПУСТИМО объявлять методы с пробелом после названия метода. Открывающую фигурную скобку НЕОБХОДИМО располагать на отдельной строке; закрывающую фигурную скобку НЕОБХОДИМО располагать на следующей строке после тела метода. НЕДОПУСТИМО оставлять пробел после открывающей круглой скобки и перед закрывающей.
В списке аргументов метода НЕДОПУСТИМЫ пробелы перед запятыми и НЕОБХОДИМ один пробел после каждой запятой.
<?php
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// тело метода
}
}
8) Список аргументов МОЖНО разбить на несколько строк. Когда список аргументов разбит на несколько строк, закрывающую круглую скобку и открывающую фигурную НЕОБХОДИМО располагать на одной отдельной строке, с одним пробелом между ними.
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// тело метода
}
}
9) При наличии ключевых слов abstract и final, НЕОБХОДИМО чтобы они предшествовали модификаторам видимости. При наличии ключевого слова static, НЕОБХОДИМО чтобы оно следовало за модификатором видимости.
<?php
namespace Vendor\Package;
abstract class ClassName
{
protected static $foo;
abstract protected function zim();
final public static function bar()
{
// тело метода
}
}
10) Анонимные функции умышленно упущены в данной статье по той причине, что курс обходит их стороной. Но никто не мешает почитать.
Заключение по стандартам кодирования
Что касается 3,4,7 стандартов, то они касательно интерфейса (ООП), автолоадера с использованием namespace (пространства имён), работа с сообщениями (взаимодействием между приложениями или его страницами). Эти темы будут рассмотрены в уроках второго уровня, именно поэтому будет написана отдельная статья по не вошедшим стандартам PSR.
Вот официальный сайт их: http://www.php-fig.org/. Сами подумайте, если их пишут разработчики известных ЦМС и Фреймворков, то круто ли это всё знать и этому следовать?! А я пока отвечу сам... да, это очень круто и, хоть перед нами и рекомендации по кодированию, и то, что они не являются обязательными для языка как такового, всё равно им следовать стоит, это моё мнение. Учитесь, запоминайте и становитесь профессионалами!
Комментарии о School-PHP (2):