Стандарты написания кода

При внесении вклада в код Symfony, вы должны следовать стандартам написания кода. Кратко говоря, вот золотое правило: Имитируйте существующий код Symfony. Большинство общедоступных пакетов и библиотек, используемых Symfony тоже следуют этим правилам, как стоит и вам.

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

Symfony следует стандартам, определённым в документах PSR-0, PSR-1, PSR-2 и PSR-4.

Так как лучше один раз увидеть, чем сто раз услышать, вот короткий пример, содержащий большинство функций, описанных ниже:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
<?php

/*
 * Этот файл является частью пакета Symfony.
 *
 * (c) Fabien Potencier <[email protected]>
 *
 * Чтобы получить полную информацию об авторском праве и лицензии, пожалуйста
 * просмотрите файл LICENSE, который поставляется с этим исходным кодом.
 */

namespace Acme;

/**
 * Coding standards demonstration.
 */
class FooBar
{
    const SOME_CONST = 42;

    /**
     * @var string
     */
    private $fooBar;

    /**
     * @param string $dummy Some argument description
     */
    public function __construct($dummy)
    {
        $this->fooBar = $this->transformText($dummy);
    }

    /**
     * @return string
     *
     * @deprecated
     */
    public function someDeprecatedMethod()
    {
        @trigger_error(sprintf('The %s() method is deprecated since version 2.8 and will be removed in 3.0. Use Acme\Baz::someMethod() instead.', __METHOD__), E_USER_DEPRECATED);

        return Baz::someMethod();
    }

    /**
     * Преобразует ввод, заданный в качестве первого аргумента.
     *
     * @param bool|string $dummy   Описание некоторого аргумента
     * @param array       $options Коллекция опций, которую нужно использовать при преобразовании
     *
     * @return string|null The transformed input
     *
     * @throws \RuntimeException When an invalid option is provided
     */
    private function transformText($dummy, array $options = array())
    {
        $defaultOptions = array(
            'some_default' => 'values',
            'another_default' => 'more values',
        );

        foreach ($options as $option) {
            if (!in_array($option, $defaultOptions)) {
                throw new \RuntimeException(sprintf('Unrecognized option "%s"', $option));
            }
        }

        $mergedOptions = array_merge(
            $defaultOptions,
            $options
        );

        if (true === $dummy) {
            return null;
        }

        if ('string' === $dummy) {
            if ('values' === $mergedOptions['some_default']) {
                return substr($dummy, 0, 5);
            }

            return ucwords($dummy);
        }
    }

    /**
     * Выполняет некоторую базовую проверку данного значения.
     *
     * @param mixed $value     Некоторое значение, которое нужно проверить
     * @param bool  $theSwitch Некоторый переключатель для контроля работы метода
     *
     * @return bool|void Резуультирующая проверка, если $theSwitch не false, иначе - void
     */
    private function reverseBoolean($value = null, $theSwitch = false)
    {
        if (!$theSwitch) {
            return;
        }

        return !$value;
    }
}

Структура

  • Добавляйте один пробел после каждой запятой-разграничителя;
  • Добавляйте один пробел вокруг бинарных операций(==, &&, ...), за исключением операции конкатенации (.);
  • Помещайте унарные операторы (!, --, ...) непосредственно с задействованной переменной;
  • Всегда используйте идентичное сравнение, кроме случаев, когда вам нужно жонглирование типами;
  • Испльзуйте условия Йоды при сопоставлении переменной с выражением, чтобы избежать случайного назначения внутри выражения условия (это применимо к ==, !=, ===, и !==);
  • Добавляйте запятую после каждого объекта массива в многстрочном массиве, даже после последнего;
  • Добавляйте пустую строку перед утверждениями return, кроме случаев, когда возврат осуществляется внутри группы утвеждений (как утверждение if);
  • Используйте return null;, когда функция ясно возвращает значения null и используйте return;, когда функция возвращает значения void;
  • Используйте скобки, чтобы обозначить тело структуры контроля независимо от количества содержащися в неё утверждений;
  • Определяйте один класс на файла - это не применимо к приватным классам помощников, которые не должны быть инстанциированы извне, и поэтому не рассматриваются автозагружаемыми стандартами PSR-0 and PSR-4;
  • Объявляйте наследуемость классов и все реализуемые интерфейсы в одной строке с именем класса;
  • Объявляйте свойства класса до методов;
  • Объявляйте вначале публичные методы, потом защищённые и потом - приватные. Исключением из этого правила являются конструктор класса и методы модульных PHP тестов setUp() и tearDown(), которые должны всегда быть первыми методами для большей удобочитаемости;
  • Объявляйте все аргументы в той же строке, что и имя метода или функции, независимо от того, сколько их;
  • Используйте круглые скобки при инстанциировании классов, независимо от количества аргументов в конструкторе;
  • Строки исключений и сообщений ошибок должны быть конкатенированы используя sprintf;
  • Вызовы trigger_error с типом E_USER_DEPRECATED должны быть переключены на согласие через оператор @. Прочтите больше в Депрекации;
  • Не используйте else, elseif, break после условий if и case, которые что-то вызывают или возвращают;
  • Не используйте пробелы вокруг относительного аксессора [ и перед относительным аксессором ].

Соглашения именования

  • Используйте camelCase, а не нижние подчёркивания, для имён переменных, функций, методов и аргументов;
  • Используйте нижние подчёркивания для имён опций и параметров;
  • Используйте пространства имён для всех классов;
  • Добавляйте к абстрактным классам префикс Abstract. Пожалуйста отметьте, что некоторые ранние классы Symfony не следуют этому соглашению и не были переименованы по причинам обратной совместимости. Однако, все новые абстрактные классы должны следовать этому соглашению именования;
  • Добавлйте к интерфейсам суффикс Interface;
  • Добавляйте к чертам суффикс Trait;
  • Добавляйте к исключениям суффикс Exception;
  • Используйте алфавитно-цифровые знаки и нижние подчёркивания для имён файлов;
  • Для типизирования в PHPDocs и приведениях, используйте bool (вместо boolean или Boolean), int (вместо integer), float (вместо double или real);
  • Не забывайте смотреть в более подробный документ Conventions для более субъективных правил именования.

Соглашения именования сервисов

  • Имя сервиса содержит группы, разделенные точками;
  • Дополнительное имя DI пакета - это первая группа (например, fos_user);
  • Используйте буквы нижнего регистра для имён сервисов и параметром (кроме случаев ссылания на переменные окружения с синтаксисом %env(VARIABLE_NAME)%);
  • Имя группы использует нотацию нижнего подчёркивания.

Документация

  • Добавляйте блоки PHPDoc для всех классов, методов и функций;
  • Группируйте аннотации вместе, чтобы аннотации одного типа следовали сразу же друг за другом, а аннотации разных типов были разделены одной пустой строкой;
  • Опускайте тег @return, если метод ничего не возвращает;
  • Аннотации @package и @subpackage не используются.

Лицензия

  • Symfony выпускается под лицензией MIT, и блок лицензии должен присутствовать сверху каждого PHP-файла, перед пространством имён.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.