Proposal for "Coding standard enhancements"

» Metadata » Status
  • Status: Proposed
» Description

The PEAR Group has voted and accepted this document. There will be no voting among developers.

Introduction

This RFC defines changes and enhancements to the current Coding Standards (CS) in PEAR. They are neccessary because the standards are not clear in some cases. With applications like PHP_CodeSniffer being used, is is important that those issues are worked out and tools can deliver reliable warnings and CS errors.

Most of the issues we currently have deal with long lines and how they should be split. General rule of thumb is that when splitting a line, the originating lines are indented by 4 spaces.
Futher, the format shall allow it to easily comment out those lines - be it for debugging or development reasons. This implies that closing braces are to be put on a line on its own, and commas at the end of a line.

While it might seem archaic to some, the 75-80 line rule is still important. Please see http://paul-m-jones.com/?p=276 for an in-depth discussion on the topic.

Split function definitions onto several lines

Functions with many parameters need to be split onto several lines to keep the 80 chars/line limit.
The first parameters may be put onto the same line as the function name if there is enough space.
Subsequent parameters on following lines are to be indented 4 spaces. The closing parenthesis and the opening brace are to be put onto the next line, on the same indentation level as the "function" keyword.

Example:

<?php

function someFunctionWithAVeryLongName($firstParameter = 'something', $secondParameter = 'booooo',
    $third = null, $fourthParameter = false, $fifthParameter = 123.12,
    $sixthParam = true
) {
    //....
?>

Split function call on several lines

The CS require lines to have a maximum length of 80 chars.
Calling functions or methods with many parameters while adhering to CS is impossible in that cases. It should be allowed to split parameters in function calls onto several lines.

Example:

<?php

$this->someObject->subObject->callThisFunctionWithALongName(
    $parameterOne, $parameterTwo,
    $aVeryLongParameterThree
);
?>

Several parameters per line should be allowed. Parameters need to be indented 4 spaces compared to the level of the function call. The opening parenthesis is to be put at the end of the function call line, the closing parenthesis gets its own line at the end of the parameters. This shows a visual end to the parameter indentations and follows the opening/closing brace rules for functions and conditionals. (See bug #11562)

The same applies not only for parameter variables, but also for nested function calls and for arrays.

Example:

<?php

$this->someObject->subObject->callThisFunctionWithALongName(
    $this->someOtherFunc(
        $this->someEvenOtherFunc(
            'Help me!',
            array(
                'foo'  => 'bar',
                'spam' => 'eggs',
            ),
            23
        ),
        $this->someEvenOtherFunc()
    ),
    $this->wowowowowow(12)
);
?>

Nesting those function parameters is allowed if it helps to make the code more readable, not only when it is necessary when the characters per line limit is reached.

Using fluent application programming interfaces often leads to many concatenated function calls. Those calls may be split onto several lines. When doing this, all subsequent lines are indented by 4 spaces and begin with the "->" arrow.

Example:

<?php

$someObject->someFunction("some", "parameter")
    ->someOtherFunc(23, 42)
    ->andAThirdFunction();
?>

Split long assigments onto several lines

Assigments may be split onto several lines when the character/line limit would be exceeded. The equal sign has to be positioned onto the following line, and indented by 4 characters.

Example:

<?php

$GLOBALS['TSFE']->additionalHeaderData[$this->strApplicationName]
    = $this->xajax->getJavascript(t3lib_extMgm::siteRelPath('nr_xajax'));
?>

Split long if statements onto several lines

Long if statements may be split onto several lines when the character/line limit would be exceeded. The conditions have to be positioned onto the following line, and indented 4 characters. The logical operators (&&, ||, etc.) should be at the beginning of the line to make it easier to comment (and exclude) the condition. The closing parenthesis and opening brace get their own line at the end of the conditions.

Keeping the operators at the beginning of the line has two advantages: It is trivial to comment out a particular line during development while keeping syntactically correct code (except of course the first line). Further is the logic kept at the front where it's not forgotten. Scanning such conditions is very easy since they are aligned below each other.

Example:

<?php

if (($condition1
    || $condition2)
    && $condition3
    && $condition4
) {
    //code here
} 
?>

The first condition may be aligned to the others.

Example:

<?php

if (   $condition1
    || $condition2
    || $condition3
) {
    //code here
}
?>
The best case is of course when the line does not need to be split. When the if clause is really long enough to be split, it might be better to simplify it. In such cases, you could express conditions as variables an compare them in the if() condition. This has the benefit of "naming" and splitting the condition sets into smaller, better understandable chunks:

<?php

$is_foo = ($condition1 || $condition2);
$is_bar = ($condition3 && $condtion4);
if ($is_foo && $is_bar) {
    // ....
}
?>

Note: There were suggestions to indent the parantheses "groups" by 1 space for each grouping. This is too hard to achieve in your coding flow, since your tab key always produces 4 spaces. Indenting the if clauses would take too much finetuning.

Ternary operators

The same rule as for if clauses also applies for the ternary operator: It may be split onto several lines, keeping the question mark and the colon at the front.


<?php

$a = $condition1 && $condition2
    ? $foo : $bar;

$b = $condition3 && $condition4
    ? $foo_man_this_is_too_long_what_should_i_do
    : $bar;
?>

Alignment of function parameters

To support readability, parameters in subsequent calls to the same function/method may be aligned by parameter name:


<?php

$this->callSomeFunction('param1',     'second',        true);
$this->callSomeFunction('parameter2', 'third',         false);
$this->callSomeFunction('3',          'verrrrrrylong', true);
?>

Alignment of assignments

To support readability, the equal signs may be aligned in block-related assignments:

<?php

$short  = foo($bar);
$longer = foo($baz);
?>

The rule can be broken when the length of the variable name is at least 8 characters longer/shorter than the previous one:

<?php

$short = foo($bar);
$thisVariableNameIsVeeeeeeeeeeryLong = foo($baz);
?>

Array formatting

Assignments in arrays may be aligned. When splitting array definitions onto several lines, the last value may also have a trailing comma. This is valid PHP syntax and helps to keep code diffs minimal:


<?php

$some_array = array(
    'foo'  => 'bar',
    'spam' => 'ham',
);
?>

Recommendation: Readability of code blocks.

Related lines of code should be grouped into blocks, seperated from each other to keep readability as high as possible. The definition of "related" depends on the code :)

For example:

<?php

if ($foo) {
    $bar = 1;
}
if ($spam) {
    $ham = 1;
}
if ($pinky) {
    $brain = 1;
}
?>

is a lot easier to read when seperated:

<?php

if ($foo) {
    $bar = 1;
}

if ($spam) {
    $ham = 1;
}

if ($pinky) {
    $brain = 1;
}
?>

Return early

To keep readability in functions and methods, it is wise to return early if simple conditions apply that can be checked at the beginning of a method:

<?php

function foo($bar, $baz)
{
    if ($foo) {
        //assume
        //that
        //here
        //is
        //the
        //whole
        //logic
        //of
        //this
        //method
        return $calculated_value;
    } else {
        return null;
    }
}
?>
It's better to return early, keeping indentation and brain power needed to follow the code low.

<?php

function foo($bar, $baz)
{
    if (!$foo) {
        return null;
    }

    //assume
    //that
    //here
    //is
    //the
    //whole
    //logic
    //of
    //this
    //method
    return $calculated_value;
}
?>

Notes

We should keep to the 4 space indentation rule. Allowing 6, 8 or any other number for "personal preference" is an absurd line in a "standard".

Of course, the best rule is keeping your code easy and clean, avoing dozens of parameters to a function ("code smell" for long parameter lists). But sometimes there is no way to avoid functions with 6 parameters, and having default values for them does not simplfy the situation. The rules here are exactly for that code lines.

Ledger Live: Elevate your crypto game with frequent updates. Explore the enhanced security measures and cutting-edge features that Ledger Live desktop brings to crypto enthusiasts, ensuring a seamless and secure management experience.

» Dependencies » Links
» Timeline » Changelog
  • First Draft: 2008-03-07
  • Proposal: 2008-03-07
  • Christian Weiske
    [2008-03-07 17:24 UTC]

    Removing superfluous spaces at the beginning of code lines - they were a leftover from the original http://wiki.pear.php.net code.

  • Christian Weiske
    [2008-08-23 09:03 UTC]

    Updated coding standards enhancement proposal according to all of the comments you made (thanks!).

  • Christian Weiske
    [2008-11-05 08:51 UTC]

    note that the group has been voting about it.

  • Thies C. Arntzen
    [2023-12-14 09:19 UTC]