PHP Coding Style

PHP Code Demarcation

PHP code must always be delimited by the full-form, standard PHP tags:

<?php
  // code goes here
?>

To remove the possibility of accidentally injecting a trailing whitespace into the output, the closing tag
(”?>”) must not be used either. The closing tag is not required by PHP.

Short tags like outputs like this are not allowed either:

”<?=$var?>”

Strings

Strings must be demarcated by the apostrophe (single quotes). This provides that PHP-Code in a string won’t be executed and HTML Outputs with a lot of double quotes is easy to write. Variable substitution in a string is only permitted by splitting the string in pieces and set the variable between two points. There always must be a space before and after the concatenation points.

// Sample String
$sampleString = 'This is a sample string.';

// Variable Substitution
$welcome = 'Hello ' . $name . ', welcome back!';

// Short SQL Query
$sql = "SELECT name FROM people WHERE id = '" . $id . "'";

// Long SQL Query
$sql = "
  SELECT `id`
       , `name`
    FROM `people`
   WHERE `name` = '" . $fName . "'
      OR `name` = '" . $lName . "'
   ORDER BY `name` ASC
  LIMIT 20;
";

All SQL Statements must be written with SQL Syntax in uppercase and stacked as shown above.

Numerically Indexed Arrays

When declaring indexed arrays with the array construct, a trailing space must be added after each comma delimiter to improve readability:

$sampleArray = array(1, 2, 3, 'Bluewater', 'Plugins');

It is also permitted to declare multiline indexed arrays using the “stacked array” construct. In this case, each successive line must be padded with spaces such that beginning of each line aligns as shown below. Each successive line also begins with a COMMA. This allows for quick and easy additions and modifications:

$sampleArray = array( 1
                    , 2
                    , 3
                    , 'Bluewater'
                    , 'Plugins'
                    , $b
                    , 56.44
                    );

Associative Arrays

When declaring associative arrays with the array construct, it is encouraged to break the statement into multiple lines (similar to “stacked arrays”). Each successive line must be padded with whitespace such that both the keys and the values are aligned:

$sampleArray = array( 'firstKey'  => 'firstValue'
                    , 'secondKey' => 'secondValue'
                    , 'thirdKey'  => 'thirdValue'
                    );

Notice that each successive line begins with the COMMA. This allows for easy insertion of new lines.

This following notation is also allowed (but the previous is preferred):

$sampleArray['firstKey']  = 'firstValue';
$sampleArray['secondKey'] = 'secondValue';
$sampleArray['thirdKey']  = 'thirdValue';

IMPORTANT: Array-Keys and -Values must always be delimited by single quotes!

Class Declarations

Classes must be named by following the Project naming conventions for Classes. The brace is always written on the line underneath the class name (”Allman Style” form). Every Class must have a documentation block that conforms to the phpDocumentor standard. Any code within a Class must be indented the standard indent of four spaces. Only one Class is permitted per PHP file. Placing additional code in a class file is permitted but discouraged. In these files, two blank lines must separate the class from any additional PHP code in the file.

This is an example of an acceptable Class declaration:

/**
 * File Docblock Here
 */

/**
 * Class Docblock Here
 */
class Bluewater_Class
{
   // Entire content of a Class must be indented four spaces
};

// eof

Class Member Properties

Member Properties must be named by following the Variable Naming Conventions. Any properties declared within a class must be listed at the top of that class, prior to declaring any methods. Every Class Property must have a Class Documentation Block that conforms to the phpDocumentor standard. The “var” construct is not permitted. Member properties always declare their visibility by using one of the “private”, “protected”, or “public” constructs. Accessing member variables directly by making them public is highly discouraged in favor of accessor methods having the “set” and “get” prefixes.

/**
 * File Docblock Here
 */

/**
 * Class Docblock Here
 */

class Bluewater_Class
{
  /**
   * Variable Docblock Here
   */
   private $_privateVar = null;

  /**
   * Variable Docblock Here
   */
   protected $_protectedVar = null;

  /**
   * Variable Docblock Here
   */
   public $publicVar = null;
}

// eof

Function and Method Declaration

Functions and Class Methods must be named by following the Function and Method Naming Conventions. Methods must always declare their visibility by using one of the private, protected, or public constructs. Functions and Class Methods must have a documentation block that conforms to the phpDocumentor standard. As with Classes, the opening brace for a function or method is always written on the line underneath the function or method name (”Allman Style” form). There is no space between the function or method name and the opening parenthesis for the arguments. This is an example of acceptable class method declarations:

/**
  * Class Docblock Here
  */
class Bluewater_Foo
{
   /**
    * Method Docblock Here
    */
    public function sampleMethod($a)
    {
        // Entire content of function must be indented four spaces
    }

   /**
    * Method Docblock Here
    */
    protected function _anotherMethod()
    {
       // ...
    }

   /**
    * Method Docblock Here
    */
    private function _anotherNewMethod(Array $b)
    {
        // ...
    }
}

// eof

Passing function or method arguments by reference is only permitted by defining the reference in the function or method declaration, as in the following example:

function sampleMethod(&$a)
{
    // ...
}

Methods and functions that use objects or arrays as arguments must be declared as the following example:

class Bluewater_Foo
{
    function objectMethod(Bluewater_Bar $sampleObject)
    {
        // ...
    }

    function arrayMethod(Array $sampleArray)
    {
        // ...
    }
}

Call-time pass by-reference is prohibited.

The return value must not be enclosed in parentheses. This can hinder readability and can also break code if a function or method is later changed to return by reference.

function foo()
{
    // Incorrect
    return($this->bar);

    // Correct
    return $this->bar;
}

Default Constructors

PHP 5.x utilizes default constructor:

need reference here!

phpDoc (unlike JavaDoc) does not automatically generate documentation for default constructors. If you don’t define a class constructor along with phpDocblock, than phpDoc does not create documentation. The question then arises: How do you add a doc comment for a default constructor? The simple answer: you don’t.

“Best Practice” would dictate that a class should never use a default constructors in public APIs: All constructors should be explicit. That is, all default constructors in public and protected classes should be turned into explicit constructor declarations with the appropriate access modifier. This explicit declaration also gives you a place to write documentation comments.

Explicit declaration helps prevents a class from inadvertently being made instantiable, as the design engineer has to actually make a conscience decision about the constructor’s access.

Note that when creating an explicit constructor, it must match precisely the declaration of the automatically generated constructor; even if the constructor should logically be protected, it must be made public to match the declaration of the automatically generated constructor, for compatibility. An appropriate phpDoc comment should then be provided. Often, the comment should be something as simple as:

// need example

Function and Method Usage

Function arguments are separated by a single trailing space after the comma delimiter. This is an example of an acceptable function call for a function that takes three arguments:

threeArguments(1, 2, 3)
{
   //....
}

Call-time pass by-reference is prohibited. Arguments to be passed by reference must be defined in the function declaration. For functions whose arguments permit arrays, the function call may include the “array” construct and can be split into multiple lines to improve readability. In these cases, the standards for writing arrays still apply:

threeArguments( array(1, 2, 3),  , 'Bluewater', 'Projects' )
 { ... }

threeArguments( array(1, 2, 3)
              , 'Bluewater'
              , 'Projects',
              )
{ ... }

if / else / else if

Control statements based on the “if”, “else”, and “else if” constructs must have a single space before the opening parenthesis of the conditional, and a single space between the closing parenthesis and opening brace. Within the conditional statements between the parentheses, operators must be separated by spaces for readability. Inner parentheses are encouraged to improve logical grouping of larger conditionals. The brace is always written on the line underneath the conditional (”Allman Style” form). The closing brace is always written on its own line. Any content within the braces must be indented four spaces.

if ($a != 2)
{
   $a = 2;
}

For “if” statements that include “else if” or “else”, the formatting must be as in these examples:

if ($a != 2)
{
   $a = 2;
}
else
{
   $a = 7;
}

if ($a != 2)
{
   $a = 2;
}
else if ($a == 3)
{
   $a = 4;
}
else
{
   $a = 7;
}

The “elseif” construct is not permitted!

Ternary conditional operator

In case of a very short “if/else” construct…

if (isset($_GET['sampleVar']))
{
    $sampleVar = $_GET['sampleVar'];
}
else
{
    $sampleVar = '';
}

… the ternary conditional operator can be used for simple “if/else” constructs:

$sampleVar = isset($_GET['sampleVar']) ? $_GET['sampleVar'] : '';

This can be simplified even further (as of PHP 5.3)

$sampleVar = isset($_GET['sampleVar']) ?: '';
[/php ]

<h4 id="switch">switch</h4>
Control statements written with the “switch” construct must have a single space before the opening parenthesis of the conditional statement, and also a single space between the closing parenthesis and the opening brace. All content within the “switch” statement must be indented four spaces. Content under each “case” statement must be indented an additional four spaces. A blank line must separate one case statement from another.

The construct “default” may never be omitted from a “switch” statement. It may be empty, but it must be defined.

It is sometimes useful to write a “case” statement which falls through to the next case by not including a “break” or “return”. To distinguish these cases from bugs, such “case” statements <strong>must</strong> contain the following comment:

[php linenumbers="false"]
// break intentionally omitted

Only “default” case may omit the “break” statement, as this is redundant to the construct of the switch structure; and it should commented that the “break” has been omitted.

switch ($sampleNumber)
{
    case 1:
    // ...
    // break intentionally omitted

    case 2:
    // ...
    break;

    case 3:
    // ...
    break;

    default:
    // ...
    // break is left out;
}

while / for / foreach

The “while”, “for” and “foreach” loops are formatted similar to the “if”, “else” and “else if” statements.

for ($i = 0; $i < 10; $i++)
{
    echo 'Hello ' . $i . "\n";
}

foreach ($sampleArray as $key => $value)
{
    echo $key . ' is ' . $value . "\n";
}

while ($row = mysql_fetch_assoc($result))
{
    echo $row['id'] . "\n";
}