Fix indentation of PHP code files with php-cs-fixer

wp78de picture wp78de · Sep 19, 2017 · Viewed 8.5k times · Source

I have several hundreds of horribly indented PHP files with mixed tabs and spaces (and even mixed line endings, I suppose) I would like to fix them with php-cs-fixer v2+.

I have configured php-cs-fixer to my needs, and the code is scrubbed accordingly - except the indentation. I have tried a minimal configuration, like shown bellow, to pin down the problem. But I cannot get the indentation fixer straight:

return PhpCsFixer\Config::create()
    ->setRules([
        '@PSR2' => true,
        'indentation_type' => true,
        'braces' => ['position_after_functions_and_oop_constructs' => 'same'],
    ])
    ->setIndent("\t")
    ->setLineEnding("\r\n")

Currently, I run this on my Windows box using the following command (here for a single file):

php-cs-fixer.bat fix new_user.php --config /full/windowspath/to/php_cs.dist

Just in case, the generated php_cs.cache (which contains the actually applied rules in JSON) file looks like this:

{
    "php": "5.6.31",
    "version": "2.6.0:v2.6.0#5642a36a60c11cdd01488d192541a89bb44a4abf",
    "rules": {
        "blank_line_after_namespace": true,
        "braces": {
            "position_after_functions_and_oop_constructs": "same"
        },
        "class_definition": true,
        "elseif": true,
        "function_declaration": true,
        "indentation_type": true,
        "line_ending": true,
        "lowercase_constants": true,
        "lowercase_keywords": true,
        "method_argument_space": {
            "ensure_fully_multiline": true
        },
        "no_break_comment": true,
        "no_closing_tag": true,
        "no_spaces_after_function_name": true,
        "no_spaces_inside_parenthesis": true,
        "no_trailing_whitespace": true,
        "no_trailing_whitespace_in_comment": true,
        "single_blank_line_at_eof": true,
        "single_class_element_per_statement": {
            "elements": ["property"]
        },
        "single_import_per_statement": true,
        "single_line_after_imports": true,
        "switch_case_semicolon_to_colon": true,
        "switch_case_space": true,
        "visibility_required": true,
        "encoding": true,
        "full_opening_tag": true
    },
    "hashes": {
        "new_students.org_.php": -151826318
    }
}

And here is some badly indented sample file content.

<?php
session_start();

  include 'connect.php';
include 'functions.php';    

$test= "abc";
    $additional_studs = "";
    if (date('m') == 12 and $term='SP') {
        $yr_suffix = date('y') + 1;
    } else {
        $yr_suffix = date('y');
    }


    function dup_stud($id, $conn)
    {//...
}

$i = 0;

I am most annoyed be lines like $test="abc"; & include 'connect.php'; with one or more leading tabs/spaces that do not get properly indented.

I am open to alternative approaches. Others must have faced formatting issues like this before.

I have also tried NetBeans, which happens to format the source beautifully, but it is tedious to open each file manually and apply the source formatting via shortcut.

Answer

Jan Tojnar picture Jan Tojnar · Sep 19, 2017

You should use braces fixer to force indentation.

The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented.

indentation_type simply enforces consistency.

But since both the fixers are already included in @PSR2 so the code should be fixed correctly.

See the relevant sections in the README.


Using your code php-cs-fixer 2.6 produces the following code

<?php
$test= "abc";
    $additional_studs = "";
    if (date('m') == 12 and $term='SP') {
        $yr_suffix = date('y') + 1;
    } else {
        $yr_suffix = date('y');
    }


    function dup_stud($id, $conn)
    {//...
    }

$i = 0;

where the indentation is only partly fixed.

I reduced it to the code below

<?php
echo "a";
    echo "b";
echo "c";

It looks like a bug in php-cs-fixer.