Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP CS Fixer - Laravel Coding Style Ruleset
<?php
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
$rules = [
'array_indentation' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'default' => 'single_space',
'operators' => ['=>' => null],
],
'blank_line_after_namespace' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => ['return'],
],
'braces' => true,
'cast_spaces' => true,
'class_attributes_separation' => [
'elements' => [
'const' => 'one',
'method' => 'one',
'property' => 'one',
'trait_import' => 'none',
],
],
'class_definition' => [
'multi_line_extends_each_single_line' => true,
'single_item_single_line' => true,
'single_line' => true,
],
'concat_space' => [
'spacing' => 'none',
],
'constant_case' => ['case' => 'lower'],
'declare_equal_normalize' => true,
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'fully_qualified_strict_types' => true, // added by Shift
'function_declaration' => true,
'function_typehint_space' => true,
'general_phpdoc_tag_rename' => true,
'heredoc_to_nowdoc' => true,
'include' => true,
'increment_style' => ['style' => 'post'],
'indentation_type' => true,
'linebreak_after_opening_tag' => true,
'line_ending' => true,
'lowercase_cast' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true, // added from Symfony
'magic_method_casing' => true, // added from Symfony
'magic_constant_casing' => true,
'method_argument_space' => [
'on_multiline' => 'ignore',
],
'multiline_whitespace_before_semicolons' => [
'strategy' => 'no_multi_line',
],
'native_function_casing' => true,
'no_alias_functions' => true,
'no_extra_blank_lines' => [
'tokens' => [
'extra',
'throw',
'use',
],
],
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => [
'use' => 'echo',
],
'no_multiline_whitespace_around_double_arrow' => true,
'no_short_bool_cast' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_around_offset' => [
'positions' => ['inside', 'outside'],
],
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_unneeded_control_parentheses' => [
'statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield'],
],
'no_unreachable_default_argument_value' => true,
'no_useless_return' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'normalize_index_brace' => true,
'not_operator_with_successor_space' => true,
'object_operator_without_whitespace' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'psr_autoloading' => true,
'phpdoc_indent' => true,
'phpdoc_inline_tag_normalizer' => true,
'phpdoc_no_access' => true,
'phpdoc_no_package' => true,
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_scalar' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_summary' => false,
'phpdoc_to_comment' => false, // override to preserve user preference
'phpdoc_tag_type' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'self_accessor' => true,
'short_scalar_cast' => true,
'simplified_null_return' => false, // disabled as "risky"
'single_blank_line_at_eof' => true,
'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => [
'elements' => ['const', 'property'],
],
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_line_comment_style' => [
'comment_types' => ['hash'],
],
'single_quote' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'switch_case_semicolon_to_colon' => true,
'switch_case_space' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'visibility_required' => [
'elements' => ['method', 'property'],
],
'whitespace_after_comma_in_array' => true,
];
$finder = Finder::create()
->in([
__DIR__ . '/app',
__DIR__ . '/config',
__DIR__ . '/database',
__DIR__ . '/resources',
__DIR__ . '/routes',
__DIR__ . '/tests',
])
->name('*.php')
->notName('*.blade.php')
->ignoreDotFiles(true)
->ignoreVCS(true);
return (new Config)
->setFinder($finder)
->setRules($rules)
->setRiskyAllowed(true)
->setUsingCache(true);
@jasperf
Copy link

jasperf commented Jun 13, 2021

Thanks @cstriuli . Appreciate the updated PHP CS Fixer configuration file a lot!

@tolgacibikci
Copy link

tolgacibikci commented Jul 4, 2021

Thanks @cstriuli

@dogeow
Copy link

dogeow commented Jul 9, 2021

Thanks @cstriuli
Although I can click emoji, However, I still want to express my thanks in words.

@adiletmaks
Copy link

adiletmaks commented Jul 11, 2021

Thanks @cstriuli

@mitoop
Copy link

mitoop commented Jul 31, 2021

Thanks @cstriuli Nice job!

@andreaselia
Copy link

andreaselia commented Aug 13, 2021

<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$rules = [
    'array_syntax' => ['syntax' => 'short'],

    'no_unused_imports' => true,
    'blank_line_after_namespace' => true,
    'blank_line_after_opening_tag' => true,
    'braces' => true,
    'cast_spaces' => true,
    'concat_space' => [
        'spacing' => 'none',
    ],
    'declare_equal_normalize' => true,
    'elseif' => true,
    'encoding' => true,
    'full_opening_tag' => true,
    'fully_qualified_strict_types' => true, // added by Shift
    'function_declaration' => true,
    'function_typehint_space' => true,
    'heredoc_to_nowdoc' => true,
    'include' => true,
    'increment_style' => ['style' => 'post'],
    'indentation_type' => true,
    'linebreak_after_opening_tag' => true,
    'line_ending' => true,
    'lowercase_cast' => true,
    'lowercase_keywords' => true,
    'lowercase_static_reference' => true, // added from Symfony
    'magic_method_casing' => true, // added from Symfony
    'magic_constant_casing' => true,
    'method_argument_space' => true,
    'native_function_casing' => true,
    'no_alias_functions' => true,
    'no_extra_blank_lines' => [
        'tokens' => [
            'extra',
            'throw',
            'use',
            'use_trait',
        ],
    ],
    'no_blank_lines_after_class_opening' => true,
    'no_blank_lines_after_phpdoc' => true,
    'no_closing_tag' => true,
    'no_empty_phpdoc' => true,
    'no_empty_statement' => true,
    'no_leading_import_slash' => true,
    'no_leading_namespace_whitespace' => true,
    'no_mixed_echo_print' => [
        'use' => 'echo',
    ],
    'no_multiline_whitespace_around_double_arrow' => true,
    'multiline_whitespace_before_semicolons' => [
        'strategy' => 'no_multi_line',
    ],
    'no_short_bool_cast' => true,
    'no_singleline_whitespace_before_semicolons' => true,
    'no_spaces_after_function_name' => true,
    'no_spaces_inside_parenthesis' => true,
    'no_trailing_comma_in_list_call' => true,
    'no_trailing_comma_in_singleline_array' => true,
    'no_trailing_whitespace' => true,
    'no_trailing_whitespace_in_comment' => true,
    'no_unreachable_default_argument_value' => true,
    'no_useless_return' => true,
    'no_whitespace_before_comma_in_array' => true,
    'no_whitespace_in_blank_line' => true,
    'normalize_index_brace' => true,
    'not_operator_with_successor_space' => true,
    'object_operator_without_whitespace' => true,
    'phpdoc_indent' => true,
    'phpdoc_no_access' => true,
    'phpdoc_no_package' => true,
    'phpdoc_no_useless_inheritdoc' => true,
    'phpdoc_scalar' => true,
    'phpdoc_single_line_var_spacing' => true,
    'phpdoc_summary' => true,
    'phpdoc_to_comment' => true,
    'phpdoc_trim' => true,
    'phpdoc_types' => true,
    'phpdoc_var_without_name' => true,
    'self_accessor' => true,
    'short_scalar_cast' => true,
    'simplified_null_return' => false, // disabled by Shift
    'single_blank_line_at_eof' => true,
    'single_blank_line_before_namespace' => true,
    'single_import_per_statement' => true,
    'single_line_after_imports' => true,
    'single_line_comment_style' => [
        'comment_types' => ['hash'],
    ],
    'single_quote' => true,
    'space_after_semicolon' => true,
    'standardize_not_equals' => true,
    'switch_case_semicolon_to_colon' => true,
    'switch_case_space' => true,
    'ternary_operator_spaces' => true,
    'trim_array_spaces' => true,
    'unary_operator_spaces' => true,
    'whitespace_after_comma_in_array' => true,

    // php-cs-fixer 3: Renamed rules
    'constant_case' => ['case' => 'lower'],
    'general_phpdoc_tag_rename' => true,
    'phpdoc_inline_tag_normalizer' => true,
    'phpdoc_tag_type' => true,
    'psr_autoloading' => true,
    'trailing_comma_in_multiline' => ['elements' => ['arrays']],

    // php-cs-fixer 3: Changed options
    'binary_operator_spaces' => [
        'default' => 'single_space',
        'operators' => ['=>' => null],
    ],
    'blank_line_before_statement' => [
        'statements' => ['return'],
    ],
    'class_attributes_separation' => [
        'elements' => [
            'const' => 'one',
            'method' => 'one',
            'property' => 'one',
        ],
    ],
    'class_definition' => [
        'multi_line_extends_each_single_line' => true,
        'single_item_single_line' => true,
        'single_line' => true,
    ],
    'ordered_imports' => [
        'sort_algorithm' => 'alpha',
    ],

    // php-cs-fixer 3: Removed rootless options (*)
    'no_unneeded_control_parentheses' => [
        'statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield'],
    ],
    'no_spaces_around_offset' => [
        'positions' => ['inside', 'outside'],
    ],
    'visibility_required' => [
        'elements' => ['property', 'method', 'const'],
    ],

];

$finder = Finder::create()
    ->in([
        __DIR__.'/app',
        __DIR__.'/config',
        __DIR__.'/database',
        __DIR__.'/resources',
        __DIR__.'/routes',
        __DIR__.'/tests',
    ])
    ->name('*.php')
    ->notName('*.blade.php')
    ->ignoreDotFiles(true)
    ->ignoreVCS(true);

return (new Config())
    ->setFinder($finder)
    ->setRules($rules)
    ->setRiskyAllowed(true)
    ->setUsingCache(true);

With the "remove unused imports" rule.

@albertoarena
Copy link

albertoarena commented Sep 6, 2021

Thanks @andreaselia

@piljac1
Copy link

piljac1 commented Sep 14, 2021

@jasonmccreary First of all, thank you for making this available to the public, it's very appreciated.

Just a question though, is there a reason why array_indentation and method_chaining_indentation were left out? It seems pretty much enforced in Laravel if not mistaken.

@jasonmccreary
Copy link

jasonmccreary commented Sep 14, 2021

@piljac1, not to my knowledge. May have just been implied. What do you believe they should be set to and I can run them through the Shift test suite to see the implications.

@piljac1
Copy link

piljac1 commented Sep 14, 2021

@jasonmccreary Well, the array_indentation is part of their StyleCI preset. As for the method_chaining_indentation, it is not, but accross their doc and their internal code, it seemed pretty consistent from what I saw.

I personally set them both to true in our company's fixer package and so far, it seems to work out well. However, it was newly instored, so I don't have long term experience with both rules.

EDIT : After review, Laravel doesn't always abide to the behavior of 'method_chaining_indentation' => true, so it is probably better if it is left out of a general Laravel preset. So that will be a rule that we will add ourselves as an in house rule. However, since the array_indentation is part of their StyleCI preset, I'm pretty sure it would be justified to add it to Shift's rules.

@laravel-shift
Copy link
Author

laravel-shift commented Nov 18, 2021

🚀 This has been updated for PHP CS Fixer version 3. 🚀

Big thanks to @cstriuli for their initial work. A few additional options have been set to preserve the previous behavior of Shift where an explicit style is not defined by Laravel. In addition, some of the option values are the same as the default. Again, these were kept to be explicit.

@lionslair
Copy link

lionslair commented Nov 19, 2021

@laravel-shift is the one at the top of the file the correct version or the one here https://gist.github.com/laravel-shift/cab527923ed2a109dda047b97d53c200#gistcomment-3860156

@andreaselia
Copy link

andreaselia commented Nov 19, 2021

@lionslair I believe it's the one at the top mate. You can tell it was updated under the "Revisions" tab.

@laravel-shift
Copy link
Author

laravel-shift commented Nov 19, 2021

@lionslair, yes, the one at the top. Note the new filename too. Anything in the comments is user contributed and may not be exactly what Shift uses.

@lionslair
Copy link

lionslair commented Nov 21, 2021

@lionslair, yes, the one at the top. Note the new filename too. Anything in the comments is user contributed and may not be exactly what Shift uses.

Thank you for confirmation

@chrillep
Copy link

chrillep commented Nov 22, 2021

as a sidenote. is there a phpcs (php_codesniffer) equivalent? This since most Static code analyzer services. CodeClimate, Codacy etc... only support it 🤔🤷‍♂️

@milanchheda
Copy link

milanchheda commented Nov 23, 2021

Thanks for this amazing configuration. I have a small problem, would appreciate if someone can help.

Double quotes are getting converted to single quotes in multiline string. I commented 'single_quote' => true,, but no luck.

@jasonmccreary
Copy link

jasonmccreary commented Nov 23, 2021

@milanchheda, this is probably the default setting now. You may want to try setting it to false or looking at other options which deal with quotes.

@chrillep
Copy link

chrillep commented Nov 26, 2021

sort order, when using "use function" imports
'ordered_imports' => [
'sort_algorithm' => 'alpha',
'imports_order' => ['const', 'class', 'function'],
],
?

https://mlocati.github.io/php-cs-fixer-configurator/#version:3.3|fixer:ordered_imports

@jasonmccreary
Copy link

jasonmccreary commented Nov 26, 2021

@chrillep what are you trying to say?

@schonhoff
Copy link

schonhoff commented Dec 30, 2021

Is there a way to get this:

$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
             ->first(fn ($json) =>
                $json->where('id', 1)
                     ->where('name', 'Victoria Faith')
                     ->missing('password')
                     ->etc()
             )
    );

(Get it from here: https://laravel.com/docs/8.x/http-tests#asserting-against-json-collections)

instead of

$response
    ->assertJson(fn (AssertableJson $json) =>$json->has(3)
             ->first(fn ($json) =>
                $json->where('id', 1)
                     ->where('name', 'Victoria Faith')
                     ->missing('password')
                     ->etc()
             )
    );

If I'm removing "no_multiline_whitespace_around_double_arrow" it will not fix arrays anymore :-(

Can someone help me? :-)

@epalmans
Copy link

epalmans commented Apr 14, 2022

trivial, but maybe this would be an addition:

'return_type_declaration' => ['space_before' => 'none'],

that checks/fixes a return type to show as

function foo(): T

... and not, as

function foo():T

...or

function foo() : T

As per https://www.php-fig.org/psr/psr-12/#45-method-and-function-arguments + https://docs.styleci.io/fixers#return_type_declaration. Docs: https://cs.symfony.com/doc/rules/function_notation/return_type_declaration.html

@chrillep
Copy link

chrillep commented Jun 27, 2022

@jasonmccreary
Copy link

jasonmccreary commented Jun 27, 2022

@chrillep, yes, Pint used this Gist as a base, but the community has since tweaked some of the rules (like one @epalmans mentioned). So if you aren't using Laravel Pint, but PHP CS Fixer directly, you may want to pull from their ruleset direction - as Shift will likely start using Pint internally.

@GlauberF
Copy link

GlauberF commented Aug 2, 2022

I don't want that space in between! and empty for example, how to disable.

Captura de Tela_selecionar área_20220802171816

@epalmans
Copy link

epalmans commented Aug 2, 2022

I don't want that space in between! and empty for example, how to disable.

Captura de Tela_selecionar área_20220802171816

set/override the not_operator_with_space rule (https://cs.symfony.com/doc/rules/operator/not_operator_with_space.html)

@GlauberF
Copy link

GlauberF commented Aug 3, 2022

@epalmans thanks!

how can i remove an unused parameter, example $model?
Captura de Tela_selecionar área_20220803145107

@epalmans
Copy link

epalmans commented Aug 3, 2022

I don’t think php-cs-fixer will do that, as it’s not necessarily a code-style issue. A static analyzer will pick up on such thing though (like PHPStan or Psalm)

@GlauberF
Copy link

GlauberF commented Aug 4, 2022

@epalmans thanks!

@chrillep
Copy link

chrillep commented Aug 8, 2022

@chrillep, yes, Pint used this Gist as a base, but the community has since tweaked some of the rules (like one @epalmans mentioned). So if you aren't using Laravel Pint, but PHP CS Fixer directly, you may want to pull from their ruleset direction - as Shift will likely start using Pint internally.

quite right - but needs some help :)
FriendsOfPHP/PHP-CS-Fixer#6441 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment