Actions

Developer Area/Coding guidelines/PHP files: Difference between revisions

From Mahara Wiki

< Developer Area‎ | Coding guidelines
(→‎Strings: updated from Developer Area/Coding guidelines)
(syntax highlight)
 
(3 intermediate revisions by the same user not shown)
Line 21: Line 21:
Example:
Example:


<source lang="php" container="div">
<syntaxhighlight lang="php">
/**
/**
  * First line is a summary of what this function does and can only be one line.
  * First line is a summary of what this function does and can only be one line.
Line 51: Line 51:
     }
     }
}
}
</source>
</syntaxhighlight>


== PHPDocumentor ==
== PHPDocumentor ==
Line 59: Line 59:


Execute from the repo root to build the full documentation.
Execute from the repo root to build the full documentation.
<source>
<syntaxhighlight lang="bash">
mkdir -p docs/complete;
mkdir -p docs/complete;
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -d ./htdocs/ -t ./docs/complete
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -d ./htdocs/ -t ./docs/complete
</source>
</syntaxhighlight>


To build a subset:
To build a subset:
<source>
<syntaxhighlight lang="bash">
mkdir -p docs/test;
mkdir -p docs/test;
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -f ./htdocs/path/to/directory/* -t ./docs/test
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -f ./htdocs/path/to/directory/* -t ./docs/test
</source>
</syntaxhighlight>


=Language Constructs=
=Language Constructs=


==Strings==
==Strings==
Line 83: Line 82:
Examples:
Examples:


<source lang="php" container="div">
<syntaxhighlight lang="php">
$a = 'This is a string.';
$a = 'This is a string.';
$b = "This's a string that's got lots of apostrophes (i.e. <b>'</b> characters), in it. Ain't it pretty nifty?";
$b = "This's a string that's got lots of apostrophes (i.e. <b>'</b> characters), in it. Ain't it pretty nifty?";
$c = "My {$field} is {$users[$1]->$field}";
$c = "My {$field} is {$users[$1]->$field}";
</source>
</syntaxhighlight>


==require/require_once/include/include_once==
==require/require_once/include/include_once==
Line 93: Line 92:
These statements should have brackets around the argument. There is no space between the statement and the bracket. In effect, this is the same as a function call.
These statements should have brackets around the argument. There is no space between the statement and the bracket. In effect, this is the same as a function call.


<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">require_once(</font><font color="#dd0000">'my/file.php'</font><font color="#007700">);<br /></font> </font> </code></div>
<syntaxhighlight lang="php">
 
require_once('my/file.php');
</syntaxhighlight>
'''NOT''':
'''NOT''':
<syntaxhighlight lang="php">
require_once 'my/file.php';
require_once ('my/file.php');
</syntaxhighlight>


<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">require_once </font><font color="#dd0000">'my/file.php'</font><font color="#007700">;<br /> require_once (</font><font color="#dd0000">'my/file.php'</font><font color="#007700">);<br /></font> </font> </code></div>
Plugin files '''must''' be included using the <code lang="php" container="div">safe_require()</code> function. This function ensures that there are no vulnerabilities in accessing a plugin file. Plugins that do not use this function to include files should be considered vulnerable to a possible security vulnerability.
 
Plugin files '''must''' be included using the [http://mahara.eduforge.org/api/mahara/core/_lib---mahara.php.html#functionsafe_require <span style="white-space: nowrap">[[Image:http.png]]safe_require</span>] function. This function ensures that there are no vulnerabilities in accessing a plugin file. Plugins that do not use this function to include files should be considered vulnerable to a possible security vulnerability.


Any include statements in the core should '''never''' have a variable in their name, to reduce the chance of an arbitary include vulnerability.
Any include statements in the core should '''never''' have a variable in their name, to reduce the chance of an arbitary include vulnerability.
Line 109: Line 111:
There is one space after each language construct, and no spaces between brackets and the arguments inside them, '''unless''' what is inside them becomes too long for one line, in which case a special format will be used.
There is one space after each language construct, and no spaces between brackets and the arguments inside them, '''unless''' what is inside them becomes too long for one line, in which case a special format will be used.


Examples of what is '''good''':
=== Examples of what is good: ===
 
<syntaxhighlight lang="php">
if (1 == 2) {
    die('omg');
}
 
while ($i < 3) {
    echo 'I am ' . $i;
}
 
for ($i = 0, $j = 7; $i < 34, $j != 3; $i++, $j--) {
    echo ($i * $j) . ' is a silly number';
}
 
// Note bracing style of else if/else clauses
// Also note: do not use elseif
if ($a == $b) {
    echo "a = b";
}
else if ($c == $d) {
    echo "c = d";
}
else {
    echo "e = ?";
}


<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">if (</font><font color="#0000bb">1 </font><font color="#007700">== </font><font color="#0000bb">2</font><font color="#007700">) {<br />     die(</font><font color="#dd0000">'omg'</font><font color="#007700">);<br /> }<br /><br /> while (</font><font color="#0000bb">$i </font><font color="#007700">&lt; </font><font color="#0000bb">3</font><font color="#007700">) {<br />     echo </font><font color="#dd0000">'I am ' </font><font color="#007700">. </font><font color="#0000bb">$i</font><font color="#007700">;<br /> }<br /><br /> for (</font><font color="#0000bb">$i </font><font color="#007700">= </font><font color="#0000bb">0</font><font color="#007700">, </font><font color="#0000bb">$j </font><font color="#007700">= </font><font color="#0000bb">7</font><font color="#007700">; </font><font color="#0000bb">$i </font><font color="#007700">&lt; </font><font color="#0000bb">34</font><font color="#007700">, </font><font color="#0000bb">$j </font><font color="#007700">!= </font><font color="#0000bb">3</font><font color="#007700">; </font><font color="#0000bb">$i</font><font color="#007700">++, </font><font color="#0000bb">$j</font><font color="#007700">--) {<br />     echo (</font><font color="#0000bb">$i </font><font color="#007700">* </font><font color="#0000bb">$j</font><font color="#007700">) . </font><font color="#dd0000">' is a silly number'</font><font color="#007700">;<br /> }<br /><br /></font><font color="#ff8000">// Note bracing style of else if/else clauses<br /> // Also note: do not use elseif<br /></font><font color="#007700">if (</font><font color="#0000bb">$a </font><font color="#007700">== </font><font color="#0000bb">$b</font><font color="#007700">) {<br />     echo </font><font color="#dd0000">"a = b"</font><font color="#007700">;<br /> }<br /> else if (</font><font color="#0000bb">$c </font><font color="#007700">== </font><font color="#0000bb">$d</font><font color="#007700">) {<br />     echo </font><font color="#dd0000">"c = d"</font><font color="#007700">;<br /> }<br /> else {<br />     echo </font><font color="#dd0000">"e = ?"</font><font color="#007700">;<br /> }<br /><br /></font><font color="#ff8000">// Ternary operator<br /></font><font color="#0000bb">$a </font><font color="#007700">= (</font><font color="#0000bb">$b </font><font color="#007700">== </font><font color="#0000bb">true</font><font color="#007700">) ? </font><font color="#dd0000">'hello' </font><font color="#007700">: </font><font color="#dd0000">'goodbye'</font><font color="#007700">;<br /></font><font color="#ff8000">// When used with other things on each side in the same statement:<br /></font><font color="#0000bb">$a </font><font color="#007700">= </font><font color="#dd0000">'foo' </font><font color="#007700">. ((</font><font color="#0000bb">$b </font><font color="#007700">== </font><font color="#0000bb">true</font><font color="#007700">) ? </font><font color="#dd0000">'hello' </font><font color="#007700">: </font><font color="#dd0000">'goodbye'</font><font color="#007700">) . </font><font color="#dd0000">'bar'</font><font color="#007700">;<br /><br /></font><font color="#ff8000">// A complicated condition. Note location of condition,<br /> // and location of ending bracket and brace.<br /> // todo: what was the decision here regarding conditions on the "if (" line?<br /></font><font color="#007700">if (<br />     </font><font color="#0000bb">$sacrificedgoats </font><font color="#007700">== </font><font color="#0000bb">$availablegoats<br />     </font><font color="#007700">&amp;&amp; (</font><font color="#0000bb">$dogs </font><font color="#007700">== </font><font color="#0000bb">$cats<br />     </font><font color="#007700">|| </font><font color="#0000bb">1 </font><font color="#007700">!= </font><font color="#0000bb">2</font><font color="#007700">)<br />     || (</font><font color="#0000bb">$yesterday </font><font color="#007700">&gt;&gt; </font><font color="#0000bb">$tomorrow </font><font color="#007700">== </font><font color="#0000bb">4</font><font color="#007700">)<br /> ) {<br />     </font><font color="#ff8000">// Do stuff<br /></font><font color="#007700">}<br /></font> </font> </code></div>
// Ternary operator
$a = ($b == true) ? 'hello' : 'goodbye';
// When used with other things on each side in the same statement:
$a = 'foo' . (($b == true) ? 'hello' : 'goodbye') . 'bar';


Examples of what is '''bad''':
// A complicated condition. Note location of condition,
// and location of ending bracket and brace.
// todo: what was the decision here regarding conditions on the "if (" line?
if (
    $sacrificedgoats == $availablegoats
    && ($dogs == $cats
    || 1 != 2)
    || ($yesterday >> $tomorrow == 4)
) {
    // Do stuff
}
</syntaxhighlight>


<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">if ( </font><font color="#0000bb">$a </font><font color="#007700">== </font><font color="#0000bb">$b </font><font color="#007700">)<br /> {<br />     echo </font><font color="#dd0000">'hi'</font><font color="#007700">;<br /> }<br /><br /> if(</font><font color="#0000bb">$c </font><font color="#007700">== </font><font color="#0000bb">$d</font><font color="#007700">) {<br />     echo </font><font color="#dd0000">'hi'</font><font color="#007700">;<br /> } else {<br />     echo </font><font color="#dd0000">'bye'</font><font color="#007700">;<br /> }<br /><br /> if (</font><font color="#0000bb">$e</font><font color="#007700">==</font><font color="#0000bb">$f</font><font color="#007700">)<br /> {<br />     echo </font><font color="#dd0000">'hi'</font><font color="#007700">;<br /> }<br /> else<br /> {<br />     echo </font><font color="#dd0000">'bye'</font><font color="#007700">;<br /> }<br /></font> </font> </code></div>
=== Examples of what is bad: ===
<syntaxhighlight lang="php">
if ( $a == $b )
{
    echo 'hi';
}


What should be '''never''' used:
if($c == $d) {
    echo 'hi';
} else {
    echo 'bye';
}


<div class="plugin tightenable"><code><font color="#000000"> <font color="#ff8000">// For a really short condition<br /></font><font color="#007700">if (</font><font color="#0000bb">$a </font><font color="#007700">== </font><font color="#0000bb">$b</font><font color="#007700">) </font><font color="#0000bb">$c </font><font color="#007700">= </font><font color="#0000bb">1</font><font color="#007700">;<br /><br /></font></font> </code></div><div id="section_7">
if ($e==$f)
{
    echo 'hi';
}
else
{
    echo 'bye';
}
</syntaxhighlight>
=== What should be never used: ===
<syntaxhighlight lang="php">
// For a really short condition
if ($a == $b) $c = 1;
</syntaxhighlight>


==Variables and Arrays==
==Variables and Arrays==
Line 133: Line 196:
Good:
Good:


<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">$found </font><font color="#007700">= </font><font color="#0000bb">false</font><font color="#007700">;<br /></font><font color="#0000bb">$ponies </font><font color="#007700">= </font><font color="#0000bb">0</font><font color="#007700">;<br /></font><font color="#0000bb">$servername </font><font color="#007700">= </font><font color="#0000bb">$overkill</font><font color="#007700">;<br /><br /></font><font color="#ff8000">// Only in relation to controlling for/while loops<br /></font><font color="#007700">for (</font><font color="#0000bb">$i </font><font color="#007700">= </font><font color="#0000bb">10</font><font color="#007700">; </font><font color="#0000bb">$i </font><font color="#007700">&gt; </font><font color="#0000bb">5</font><font color="#007700">; </font><font color="#0000bb">$i</font><font color="#007700">--) {<br />     echo </font><font color="#0000bb">$i</font><font color="#007700">;<br /> }<br /><br /></font><font color="#ff8000">// Aligning = signs<br /></font><font color="#0000bb">$mine   </font><font color="#007700">= </font><font color="#0000bb">0</font><font color="#007700">;<br /></font><font color="#0000bb">$yours  </font><font color="#007700">= </font><font color="#0000bb">0</font><font color="#007700">;<br /></font><font color="#0000bb">$theirs </font><font color="#007700">= </font><font color="#0000bb">0</font><font color="#007700">;<br /><br /></font><font color="#ff8000">// Only if the number of elements to initialise is small.<br /></font><font color="#0000bb">$array </font><font color="#007700">= array(</font><font color="#0000bb">1 </font><font color="#007700">=&gt; </font><font color="#dd0000">'hello'</font><font color="#007700">);<br /><br /></font><font color="#ff8000">// If large number of elements to initialise:<br /></font><font color="#0000bb">$array </font><font color="#007700">= array(<br />     </font><font color="#0000bb">1  </font><font color="#007700">=&gt; </font><font color="#dd0000">'hello'</font><font color="#007700">,<br />     </font><font color="#0000bb">2  </font><font color="#007700">=&gt; </font><font color="#dd0000">'goodbye'</font><font color="#007700">,<br />     </font><font color="#0000bb">10 </font><font color="#007700">=&gt; </font><font color="#dd0000">'erm'<br /></font><font color="#007700">);<br /></font> </font> </code></div>
<syntaxhighlight lang="php>
$found = false;
$ponies = 0;
$servername = $overkill;
 
// Only in relation to controlling for/while loops
for ($i = 10; $i > 5; $i--) {
    echo $i;
}
 
// Aligning = signs
$mine  = 0;
$yours  = 0;
$theirs = 0;
 
// Only if the number of elements to initialise is small.
$array = array(1 => 'hello');
 
// If large number of elements to initialise:
$array = array(
    1  => 'hello',
    2  => 'goodbye',
    10 => 'erm'
);
</syntaxhighlight>


Bad:
Bad:
<syntaxhighlight lang="php">
// Negative name
$notfound = true;
// Underscores
$my_variable = '';
// Hungarian. Eew....
$count_i = 6;
// Uppercase letters
$myFish = $yourFish;


<div class="plugin tightenable"><code><font color="#000000"> <font color="#ff8000">// Negative name<br /></font><font color="#0000bb">$notfound </font><font color="#007700">= </font><font color="#0000bb">true</font><font color="#007700">;<br /></font><font color="#ff8000">// Underscores<br /></font><font color="#0000bb">$my_variable </font><font color="#007700">= </font><font color="#dd0000"><nowiki>''</nowiki></font><font color="#007700">;<br /></font><font color="#ff8000">// Hungarian. Eew....<br /></font><font color="#0000bb">$count_i </font><font color="#007700">= </font><font color="#0000bb">6</font><font color="#007700">;<br /></font><font color="#ff8000">// Uppercase letters<br /></font><font color="#0000bb">$myFish </font><font color="#007700">= </font><font color="#0000bb">$yourFish</font><font color="#007700">;<br /><br /></font><font color="#ff8000">// Not necessarily "bad", just not for this project<br /></font><font color="#0000bb">$array </font><font color="#007700">= array(<br />                 </font><font color="#0000bb">1 </font><font color="#007700">=&gt; </font><font color="#dd0000">'hello'</font><font color="#007700">,<br />                 </font><font color="#0000bb">2 </font><font color="#007700">=&gt; </font><font color="#dd0000">'goodbye'</font><font color="#007700">,<br />                 </font><font color="#0000bb">10 </font><font color="#007700">=&gt; </font><font color="#dd0000">'erm'<br />               </font><font color="#007700">);<br /></font> </font> </code></div></div><div id="section_8">
// Not necessarily "bad", just not for this project
$array = array(
                1 => 'hello',
                2 => 'goodbye',
                10 => 'erm'
              );
</syntaxhighlight>


==Binary Operators==
==Binary Operators==


Always have a space on each side:
Always have a space on each side:
<syntaxhighlight lang="php>
echo 1 + 2;
if (1 == 2)
echo 'hello' . ' world';
</syntaxhighlight>


<div class="plugin tightenable"><code><font color="#000000"> <font color="#007700">echo </font><font color="#0000bb">1 </font><font color="#007700">+ </font><font color="#0000bb">2</font><font color="#007700">;<br /> if (</font><font color="#0000bb">1 </font><font color="#007700">== </font><font color="#0000bb">2</font><font color="#007700">)<br /> echo </font><font color="#dd0000">'hello' </font><font color="#007700">. </font><font color="#dd0000">' world'</font><font color="#007700">;<br /></font> </font> </code></div>
<syntaxhighlight lang="text" inline>||</syntaxhighlight> and <syntaxhighlight lang="text" inline>&&</syntaxhighlight> will always be used for <syntaxhighlight lang="text" inline>or</syntaxhighlight> and <syntaxhighlight lang="text" inline>and</syntaxhighlight> respectively. Resolve priority collisions with extra brackets as required.
 
<nowiki>|| and &amp;&amp; will always be used for 'or' and 'and' respectively. Resolve priority collisions with extra brackets as required.</nowiki>


==Functions and Methods==
==Functions and Methods==


'''Declaration:'''
'''Declaration:'''
<syntaxhighlight lang="php">
/**
* PHPDoc comment describing the function
*
* Note how the default value has no spaces
*/
function foo($a, Class $b, $c='') {
    // source
    return $value;
}
class FooBar extends Bar {
    /**
    * PHPDoc for the field
    *
    * For this project, do not use doThis.
    */
    public function do_this($c, $d) {
        // source
    }


<div class="plugin tightenable"><code><font color="#000000"> <font color="#ff8000">/**<br /> * PHPDoc comment describing the function<br /> *<br /> * Note how the default value has no spaces<br /> */<br /></font><font color="#007700">function </font><font color="#0000bb">foo</font><font color="#007700">(</font><font color="#0000bb">$a</font><font color="#007700">, Class </font><font color="#0000bb">$b</font><font color="#007700">, </font><font color="#0000bb">$c</font><font color="#007700">=</font><font color="#dd0000"><nowiki>''</nowiki></font><font color="#007700">) {<br />     </font><font color="#ff8000">// source<br />     </font><font color="#007700">return </font><font color="#0000bb">$value</font><font color="#007700">;<br /> }<br /><br /> class </font><font color="#0000bb">FooBar </font><font color="#007700">extends </font><font color="#0000bb">Bar </font><font color="#007700">{<br /><br />     </font><font color="#ff8000">/**<br />      * PHPDoc for the field<br />      *<br />      * For this project, do not use doThis.<br />      */<br />     </font><font color="#0000bb">public </font><font color="#007700">function </font><font color="#0000bb">do_this</font><font color="#007700">(</font><font color="#0000bb">$c</font><font color="#007700">, </font><font color="#0000bb">$d</font><font color="#007700">) {<br />         </font><font color="#ff8000">// source<br />     </font><font color="#007700">}<br /><br /> }<br /></font> </font> </code></div>
}
</syntaxhighlight>


'''Calling:'''
'''Calling:'''


<div class="plugin tightenable"><code><font color="#000000"> <font color="#0000bb">$result </font><font color="#007700">= </font><font color="#0000bb">foo</font><font color="#007700">(</font><font color="#0000bb">$bar</font><font color="#007700">, </font><font color="#0000bb">$baz</font><font color="#007700">);<br /></font><font color="#0000bb">$mine </font><font color="#007700">= </font><font color="#0000bb">$object</font><font color="#007700">-&gt;</font><font color="#0000bb">method</font><font color="#007700">(</font><font color="#0000bb">$a</font><font color="#007700">, </font><font color="#0000bb">$b</font><font color="#007700">);<br /><br /></font></font></code></div></div>
<syntaxhighlight lang="php">
$result = foo($bar, $baz);
$mine = $object->method($a, $b);
</syntaxhighlight>

Latest revision as of 15:11, 25 February 2022

This page documents the coding conventions used by Mahara for PHP files. Everything that ends up in the git repository (other than third-party code) should follow these standards.

You can also have a look at the Reviewer's manual to see what reviewers will look at when looking at code submissions.

For other languages, use the links at the main guideline page.

The Basics

All files must adhere to the BasicPHPFileTemplates. There are slightly different templates depending on whether the script is to be included or whether it is to be directly hit.

Indentation is using four (4) spaces. There is no requirement that the scripts are wrapped at 80 columns, however developers are asked to wrap long lines sensibly.

Documenting Code

  • Comments at the head of files, functions, classes, etc should use the /** ... */ comment form for compatibility with PHPDoc and JSDoc.
  • Explanatory comments in the body of the code should use only // comment markers, regardless of the length of the comment.
    • This allows /* ... */ markers to be used for quick mass commenting during debugging.
  • Comments about a line of code should be placed on their own line above that line of code, rather than at the end of it.
    • This makes them more visible to people scanning the page, and ensures they won't be hidden off the side of the page if the reader's editor window is small.

Example:

/**
 * First line is a summary of what this function does and can only be one line.
 *
 * More detail can be presented with a blank line between the summary
 * and description. This can be a multiline block.
 *
 * The description can also be multiple paragraphs.  The description ends with a
 * blank line if there are any @tags that follow.
 *
 * @param boolean $bar description of the purpose of $bar
 * @param string $baz description of the purpose of $baz
 * @param array $qux description of the purpose of $qux
 * @return array|string This function either returns $qux with $baz added to it, or $baz with $bar added to it
 */
function foo($bar, $baz='bax', $qux=array()) {
    
    // This part is difficult and requires a long
    // explanation. This is that explanation. I am
    // still typing to see if I can make it to four
    // lines.
    if ($bar) {
        // put it on the end
        $qux[] = $baz;
        return $qux;
    } else {
        // I'm sure this makes sense somehow
        return $baz || ((string) $bar);
    }
}

PHPDocumentor

Building local docs is simple enough. We recommend using the official Docker build at phpdoc/phpdoc.

Your experience with the actual documentation may vary. There has been a recent push this year (2021) to get the local documentation more fully complete.

Execute from the repo root to build the full documentation.

mkdir -p docs/complete;
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -d ./htdocs/ -t ./docs/complete

To build a subset:

mkdir -p docs/test;
docker run --rm -v ${PWD}:/data phpdoc/phpdoc  -f ./htdocs/path/to/directory/* -t ./docs/test

Language Constructs

Strings

Recommended:

  • Strings should be quoted with single quotes (')
    • Unless you are interpolating a variable
    • Or writing a string with lots of single quotes in it.
  • Variable interpolations should be written with {curly braces} around them.

Examples:

$a = 'This is a string.';
$b = "This's a string that's got lots of apostrophes (i.e. <b>'</b> characters), in it. Ain't it pretty nifty?";
$c = "My {$field} is {$users[$1]->$field}";

require/require_once/include/include_once

These statements should have brackets around the argument. There is no space between the statement and the bracket. In effect, this is the same as a function call.

require_once('my/file.php');

NOT:

require_once 'my/file.php';
require_once ('my/file.php');

Plugin files must be included using the safe_require() function. This function ensures that there are no vulnerabilities in accessing a plugin file. Plugins that do not use this function to include files should be considered vulnerable to a possible security vulnerability.

Any include statements in the core should never have a variable in their name, to reduce the chance of an arbitary include vulnerability.

The include path is set automatically to be the current directory plus the lib directory - there is no need to specify an absolute directory path.

if/while/for statements

There is one space after each language construct, and no spaces between brackets and the arguments inside them, unless what is inside them becomes too long for one line, in which case a special format will be used.

Examples of what is good:

if (1 == 2) {
    die('omg');
}

while ($i < 3) {
    echo 'I am ' . $i;
}

for ($i = 0, $j = 7; $i < 34, $j != 3; $i++, $j--) {
    echo ($i * $j) . ' is a silly number';
}

// Note bracing style of else if/else clauses
// Also note: do not use elseif
if ($a == $b) {
    echo "a = b";
}
else if ($c == $d) {
    echo "c = d";
}
else {
    echo "e = ?";
}

// Ternary operator
$a = ($b == true) ? 'hello' : 'goodbye';
// When used with other things on each side in the same statement:
$a = 'foo' . (($b == true) ? 'hello' : 'goodbye') . 'bar';

// A complicated condition. Note location of condition,
// and location of ending bracket and brace.
// todo: what was the decision here regarding conditions on the "if (" line?
if (
    $sacrificedgoats == $availablegoats
    && ($dogs == $cats
    || 1 != 2)
    || ($yesterday >> $tomorrow == 4)
) {
    // Do stuff
}

Examples of what is bad:

if ( $a == $b )
{
    echo 'hi';
}

if($c == $d) {
    echo 'hi';
} else {
    echo 'bye';
}

if ($e==$f)
{
    echo 'hi';
}
else
{
    echo 'bye';
}

What should be never used:

// For a really short condition
if ($a == $b) $c = 1;

Variables and Arrays

Variables should be named with no underscores, and no capital letters. This policy may become more lenient in future if variable names are discovered that are not easily readable without underscores.

Do not name variables as negatives where possible - always use positive names and logical inversion (!) where required.

Hungarian notation is forbidden.

When related variables are initialised, the = signs for them should line up. Other than that, aligning = signs for variable assignment is up to the developer, although they should use common sense in such decisions.

Good:

$found = false;
$ponies = 0;
$servername = $overkill;

// Only in relation to controlling for/while loops
for ($i = 10; $i > 5; $i--) {
    echo $i;
}

// Aligning = signs
$mine   = 0;
$yours  = 0;
$theirs = 0;

// Only if the number of elements to initialise is small.
$array = array(1 => 'hello');

// If large number of elements to initialise:
$array = array(
    1  => 'hello',
    2  => 'goodbye',
    10 => 'erm'
);

Bad:

// Negative name
$notfound = true;
// Underscores
$my_variable = '';
// Hungarian. Eew....
$count_i = 6;
// Uppercase letters
$myFish = $yourFish;

// Not necessarily "bad", just not for this project
$array = array(
                1 => 'hello',
                2 => 'goodbye',
                10 => 'erm'
              );

Binary Operators

Always have a space on each side:

echo 1 + 2;
if (1 == 2)
echo 'hello' . ' world';

|| and && will always be used for or and and respectively. Resolve priority collisions with extra brackets as required.

Functions and Methods

Declaration:

/**
 * PHPDoc comment describing the function
 *
 * Note how the default value has no spaces
 */
function foo($a, Class $b, $c='') {
    // source
    return $value;
}

class FooBar extends Bar {

    /**
     * PHPDoc for the field
     *
     * For this project, do not use doThis.
     */
    public function do_this($c, $d) {
        // source
    }

}

Calling:

$result = foo($bar, $baz);
$mine = $object->method($a, $b);