mirror of
https://github.com/symfony/symfony-docs.git
synced 2026-03-24 00:32:14 +01:00
329 lines
12 KiB
ReStructuredText
329 lines
12 KiB
ReStructuredText
Coding Standards
|
|
================
|
|
|
|
Symfony code is contributed by thousands of developers around the world. To make
|
|
every piece of code look and feel familiar, Symfony defines some coding standards
|
|
that all contributions must follow.
|
|
|
|
These Symfony coding standards are based on the `PSR-1`_, `PSR-2`_, `PSR-4`_
|
|
and `PSR-12`_ standards, so you may already know most of them.
|
|
|
|
Making your Code Follow the Coding Standards
|
|
--------------------------------------------
|
|
|
|
Instead of reviewing your code manually, Symfony makes it simple to ensure that
|
|
your contributed code matches the expected code syntax. First, install the
|
|
`PHP CS Fixer tool`_ and then, run this command to fix any problem:
|
|
|
|
.. code-block:: terminal
|
|
|
|
$ cd your-project/
|
|
$ php php-cs-fixer.phar fix -v
|
|
|
|
If you forget to run this command and make a pull request with any syntax issue,
|
|
our automated tools will warn you about that and will provide the solution.
|
|
|
|
Symfony Coding Standards in Detail
|
|
----------------------------------
|
|
|
|
If you want to learn about the Symfony coding standards in detail, here's a
|
|
short example containing most features described below::
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Acme;
|
|
|
|
use Other\Qux;
|
|
|
|
/**
|
|
* Coding standards demonstration.
|
|
*/
|
|
class FooBar
|
|
{
|
|
public const SOME_CONST = 42;
|
|
|
|
private string $fooBar;
|
|
|
|
/**
|
|
* @param $dummy some argument description
|
|
*/
|
|
public function __construct(
|
|
string $dummy,
|
|
private Qux $qux,
|
|
) {
|
|
$this->fooBar = $this->transformText($dummy);
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
*/
|
|
public function someDeprecatedMethod(): string
|
|
{
|
|
trigger_deprecation('symfony/package-name', '5.1', 'The %s() method is deprecated, use Acme\Baz::someMethod() instead.', __METHOD__);
|
|
|
|
return Baz::someMethod();
|
|
}
|
|
|
|
/**
|
|
* Transforms the input given as the first argument.
|
|
*
|
|
* @param $options an options collection to be used within the transformation
|
|
*
|
|
* @throws \RuntimeException when an invalid option is provided
|
|
*/
|
|
private function transformText(bool|string $dummy, array $options = []): ?string
|
|
{
|
|
$defaultOptions = [
|
|
'some_default' => 'values',
|
|
'another_default' => 'more values',
|
|
];
|
|
|
|
foreach ($options as $name => $value) {
|
|
if (!array_key_exists($name, $defaultOptions)) {
|
|
throw new \RuntimeException(sprintf('Unrecognized option "%s"', $name));
|
|
}
|
|
}
|
|
|
|
$mergedOptions = array_merge($defaultOptions, $options);
|
|
|
|
if (true === $dummy) {
|
|
return 'something';
|
|
}
|
|
|
|
if (\is_string($dummy)) {
|
|
if ('values' === $mergedOptions['some_default']) {
|
|
return substr($dummy, 0, 5);
|
|
}
|
|
|
|
return ucwords($dummy);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Performs some basic operations for a given value.
|
|
*/
|
|
private function performOperations(mixed $value = null, bool $theSwitch = false): void
|
|
{
|
|
if (!$theSwitch) {
|
|
return;
|
|
}
|
|
|
|
$this->qux->doFoo($value);
|
|
$this->qux->doBar($value);
|
|
}
|
|
}
|
|
|
|
Structure
|
|
~~~~~~~~~
|
|
|
|
* Add a single space after each comma delimiter;
|
|
|
|
* Add a single space around binary operators (``==``, ``&&``, ...), with
|
|
the exception of the concatenation (``.``) operator;
|
|
|
|
* Place unary operators (``!``, ``--``, ...) adjacent to the affected variable;
|
|
|
|
* Always use `identical comparison`_ unless you need type juggling;
|
|
|
|
* Use `Yoda conditions`_ when checking a variable against an expression to avoid
|
|
an accidental assignment inside the condition statement (this applies to ``==``,
|
|
``!=``, ``===``, and ``!==``);
|
|
|
|
* Add a comma after each array item in a multi-line array, even after the
|
|
last one;
|
|
|
|
* Add a blank line before ``return`` statements, unless the return is alone
|
|
inside a statement-group (like an ``if`` statement);
|
|
|
|
* Use ``return null;`` when a function explicitly returns ``null`` values and
|
|
use ``return;`` when the function returns ``void`` values;
|
|
|
|
* Do not add the ``void`` return type to methods in tests;
|
|
|
|
* Use braces to indicate control structure body regardless of the number of
|
|
statements it contains;
|
|
|
|
* Define one class per file - this does not apply to private helper classes
|
|
that are not intended to be instantiated from the outside and thus are not
|
|
concerned by the `PSR-0`_ and `PSR-4`_ autoload standards;
|
|
|
|
* Declare the class inheritance and all the implemented interfaces on the same
|
|
line as the class name;
|
|
|
|
* Declare class properties before methods;
|
|
|
|
* Declare public methods first, then protected ones and finally private ones.
|
|
The exceptions to this rule are the class constructor and the ``setUp()`` and
|
|
``tearDown()`` methods of PHPUnit tests, which must always be the first methods
|
|
to increase readability;
|
|
|
|
* Declare all the arguments on the same line as the method/function name, no
|
|
matter how many arguments there are. The only exception are constructor methods
|
|
using `constructor property promotion`_, where each parameter must be on a new
|
|
line with `trailing comma`_;
|
|
|
|
* Use parentheses when instantiating classes regardless of the number of
|
|
arguments the constructor has;
|
|
|
|
* Exception and error message strings must be concatenated using :phpfunction:`sprintf`;
|
|
|
|
* Exception and error messages must not contain backticks,
|
|
even when referring to a technical element (such as a method or variable name).
|
|
Double quotes must be used at all time:
|
|
|
|
.. code-block:: diff
|
|
|
|
- Expected `foo` option to be one of ...
|
|
+ Expected "foo" option to be one of ...
|
|
|
|
* Exception and error messages must start with a capital letter and finish with a dot ``.``;
|
|
|
|
* Exception, error and deprecation messages containing a class name must
|
|
use ``get_debug_type()`` instead of ``::class`` to retrieve it:
|
|
|
|
.. code-block:: diff
|
|
|
|
- throw new \Exception(sprintf('Command "%s" failed.', $command::class));
|
|
+ throw new \Exception(sprintf('Command "%s" failed.', get_debug_type($command)));
|
|
|
|
* Do not use ``else``, ``elseif``, ``break`` after ``if`` and ``case`` conditions
|
|
which return or throw something;
|
|
|
|
* Do not use spaces around ``[`` offset accessor and before ``]`` offset accessor;
|
|
|
|
* Add a ``use`` statement for every class that is not part of the global namespace;
|
|
|
|
* When PHPDoc tags like ``@param`` or ``@return`` include ``null`` and other
|
|
types, always place ``null`` at the end of the list of types.
|
|
|
|
Naming Conventions
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
* Use `camelCase`_ for PHP variables, function and method names, arguments
|
|
(e.g. ``$acceptableContentTypes``, ``hasSession()``);
|
|
|
|
* Use `snake_case`_ for configuration parameters, route names and Twig template
|
|
variables (e.g. ``framework.csrf_protection``, ``http_status_code``);
|
|
|
|
* Use SCREAMING_SNAKE_CASE for constants (e.g. ``InputArgument::IS_ARRAY``);
|
|
|
|
* Use `UpperCamelCase`_ for enumeration cases (e.g. ``InputArgumentMode::IsArray``);
|
|
|
|
* Use namespaces for all PHP classes, interfaces, traits and enums and
|
|
`UpperCamelCase`_ for their names (e.g. ``ConsoleLogger``);
|
|
|
|
* Prefix all abstract classes with ``Abstract`` except PHPUnit ``*TestCase``.
|
|
Please note some early Symfony classes do not follow this convention and
|
|
have not been renamed for backward compatibility reasons. However, all new
|
|
abstract classes must follow this naming convention;
|
|
|
|
* Suffix interfaces with ``Interface``;
|
|
|
|
* Suffix traits with ``Trait``;
|
|
|
|
* Don't use a dedicated suffix for classes or enumerations (e.g. like ``Class``
|
|
or ``Enum``), except for the cases listed below.
|
|
|
|
* Suffix exceptions with ``Exception``;
|
|
|
|
* Prefix PHP attributes that relate to service configuration with ``As``
|
|
(e.g. ``#[AsCommand]``, ``#[AsEventListener]``, etc.);
|
|
|
|
* Prefix PHP attributes that relate to controller arguments with ``Map``
|
|
(e.g. ``#[MapEntity]``, ``#[MapCurrentUser]``, etc.);
|
|
|
|
* Use UpperCamelCase for naming PHP files (e.g. ``EnvVarProcessor.php``) and
|
|
snake case for naming Twig templates and web assets (``section_layout.html.twig``,
|
|
``index.scss``);
|
|
|
|
* For type-hinting in PHPDocs and casting, use ``bool`` (instead of ``boolean``
|
|
or ``Boolean``), ``int`` (instead of ``integer``), ``float`` (instead of
|
|
``double`` or ``real``);
|
|
|
|
* Don't forget to look at the more verbose :doc:`conventions </contributing/code/conventions>` document for
|
|
more subjective naming considerations.
|
|
|
|
.. _service-naming-conventions:
|
|
|
|
Service Naming Conventions
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
* A service name must be the same as the fully qualified class name (FQCN) of
|
|
its class (e.g. ``App\EventSubscriber\UserSubscriber``);
|
|
|
|
* If there are multiple services for the same class, use the FQCN for the main
|
|
service and use lowercase and underscored names for the rest of services.
|
|
Optionally divide them in groups separated with dots (e.g.
|
|
``something.service_name``, ``fos_user.something.service_name``);
|
|
|
|
* Use lowercase letters for parameter names (except when referring
|
|
to environment variables with the ``%env(VARIABLE_NAME)%`` syntax);
|
|
|
|
* Add class aliases for public services (e.g. alias ``Symfony\Component\Something\ClassName``
|
|
to ``something.service_name``).
|
|
|
|
Documentation
|
|
~~~~~~~~~~~~~
|
|
|
|
* Add PHPDoc blocks for classes, methods, and functions only when they add
|
|
relevant information that does not duplicate the name, native type
|
|
declaration or context (e.g. ``instanceof`` checks);
|
|
|
|
* Only use annotations and types defined in `the PHPDoc reference`_. In
|
|
order to improve types for static analysis, the following annotations are
|
|
also allowed:
|
|
|
|
* `Generics`_, with the exception of ``@template-covariant``.
|
|
* `Conditional return types`_ using the vendor-prefixed ``@psalm-return``;
|
|
* `Class constants`_;
|
|
* `Callable types`_;
|
|
|
|
* Group annotations together so that annotations of the same type immediately
|
|
follow each other, and annotations of a different type are separated by a
|
|
single blank line;
|
|
|
|
* Omit the ``@return`` annotation if the method does not return anything;
|
|
|
|
* Don't use one-line PHPDoc blocks on classes, methods and functions, even
|
|
when they contain just one annotation (e.g. don't put ``/** {@inheritdoc} */``
|
|
in a single line);
|
|
|
|
* When adding a new class or when making significant changes to an existing class,
|
|
an ``@author`` tag with personal contact information may be added, or expanded.
|
|
Please note it is possible to have the personal contact information updated or
|
|
removed per request to the :doc:`core team </contributing/core_team>`.
|
|
|
|
License
|
|
~~~~~~~
|
|
|
|
* Symfony is released under the MIT license, and the license block has to be
|
|
present at the top of every PHP file, before the namespace.
|
|
|
|
.. _`PHP CS Fixer tool`: https://cs.symfony.com/
|
|
.. _`PSR-0`: https://www.php-fig.org/psr/psr-0/
|
|
.. _`PSR-1`: https://www.php-fig.org/psr/psr-1/
|
|
.. _`PSR-2`: https://www.php-fig.org/psr/psr-2/
|
|
.. _`PSR-4`: https://www.php-fig.org/psr/psr-4/
|
|
.. _`PSR-12`: https://www.php-fig.org/psr/psr-12/
|
|
.. _`identical comparison`: https://www.php.net/manual/en/language.operators.comparison.php
|
|
.. _`Yoda conditions`: https://en.wikipedia.org/wiki/Yoda_conditions
|
|
.. _`camelCase`: https://en.wikipedia.org/wiki/Camel_case
|
|
.. _`UpperCamelCase`: https://en.wikipedia.org/wiki/Camel_case
|
|
.. _`snake_case`: https://en.wikipedia.org/wiki/Snake_case
|
|
.. _`constructor property promotion`: https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion
|
|
.. _`trailing comma`: https://wiki.php.net/rfc/trailing_comma_in_parameter_list
|
|
.. _`the PHPDoc reference`: https://docs.phpdoc.org/3.0/guide/references/phpdoc/index.html
|
|
.. _`Conditional return types`: https://psalm.dev/docs/annotating_code/type_syntax/conditional_types/
|
|
.. _`Class constants`: https://psalm.dev/docs/annotating_code/type_syntax/value_types/#regular-class-constants
|
|
.. _`Callable types`: https://psalm.dev/docs/annotating_code/type_syntax/callable_types/
|
|
.. _`Generics`: https://psalm.dev/docs/annotating_code/templated_annotations/
|