RSS

Neil Crookes

Learnings and Teachings on Web Application Development & CakePHP

Aug

30

Coding Style Guide

The coding style guide I’ve put in place at work to enhance the quality, legibility and maintainability of the code produced by my team. Based heavily on the CakePHP Coding Standards, with a few additional guidelines I’ve found important.

Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot

This is the coding style guide I’ve put in place at my work to try and ensure all my team is singing from the same song sheet and writing code in the same style. Its is almost wholly based on the CakePHP Coding Standards but has some extra guidelines and other stuff.

I think its hugely important for a team of programmers to all code in the same style. It promotes legibility and maintainability. At some point of his career a programmer will inevitably have to work on someone else’s code, if you’ve done it already and the code you’ve worked was not written the way you do it, you’ll know the feeling of bemusement, confusion and frustration you get when you need to make an update. If you haven’t had this dubious pleasure, why not avoid it altogether by having a coding style guide, like this one?

PHP tags

Always use long tags:

<?php
?>

Never use short tags:

<?
?>

or the short version of echo commonly used in views:

<?= $var ?>

as this can cause problems with xml files.

Indentation

One tab should be used for one indentation level. A tab should use spaces rather than a tab character so indentation is preserved and consistent across platforms and media. Tab-width: 2 spaces. This can normally be configured in your editor when you hit the tab key. Ensure everyone working on the project uses this convention otherwise merging changes in subversion can be a pain.

// base level
// level 1
// level 2
// level 1
// base level

Control structures

Control structures are for example “if”, “for”, “foreach”, “while”, “switch” etc. Below, an example with “if”:

if ((expr_1) || (expr_2 )) {
// action_1;
} elseif (!(expr_3) && (expr_4)) {
// action_2;
} else {
// default_action;
}

In the control structures there should be one space between the last parenthesis and the opening bracket.

Always use curly brackets in control structures, even if they are not needed. They increase the readability of the code, and they give you fewer logical errors.

Opening curly brackets should be placed on the same line as the control structure. Closing curly brackets should be placed on new lines, and they should have same indentation level as the control structure. The statement included in curly brackets should begin on a new line, and code contained within it should gain a new level of indentation. (K&R style)

// wrong - no brackets, badly placed statement
if (expr) statement;
// wrong - no brackets
if (expr)
statement;
// good
if (expr) {
statement;
}

Where multiple comparisons exist in a condition, each comparison should be parenthesised to clearly define as a separate comparison. e.g.

if($a == 'q' || $a == 'r')

Should be written as:

if(($a == 'q') || ($a == 'r'))

When writing control structures in views, follow guidelines in the “PHP code in views” section of this document.

Ternary Operator

Only use the ternary operator (<?php $a = $b == $c ? $d : $e ?>) for very simple comparisons. Using full if-else calls makes code more readable and easier to debug. Don’t nest ternary operators.

Function calls

Functions should be called without space between function’s name and starting bracket. There should be one space between every parameter of a function call.

$var = foo($bar, $bar2, $bar3);

As you can see above there should be one space on both sides of equals sign. To increase the redability of the code you can add spaces before the equals sign, but only in the case of a multiple function call presented below:

$varShort = foo($bar1);
$variableLong = foo($bar1);

String definition

All strings should be delimited by apostrophes ‘ unless quotes ” are required for interpolation purposes such as if the string contains apostrophes, variables, newline characters etc.

$string1 = 'This is a normal string so it delimited by apostrophes';
$string2 = "This string contains an apostrophe ', a $variable and\nspans 2 lines";

Array definition

Arrays should be defined thus:

$array = array(
'key1' => array(
'key1.1' => 'value1',
'key1.2' => array(
'key1.2.1' => 'value2',
),
),
'key2' => 'value',
);

unless the array is small…

$array = array('red', 'blue', 'green');

Method definition

Example of a function definition:

function someFunction($arg1, $arg2 = '') {
}

Parameters with a default value, should be placed last in function definition. Try to make your functions return something, at least true or false – so it can be determined whether the function call was successful.

Operators

Operators should be surrounded by a single space on each side. Example:

$x = $y + $z;

Commenting code


/**
* Comments that span multiple lines
* should use this style.
*/
// Use this for single line comments

Classes, their methods and properties and procedural functions should be immediately preceded by comments that include some or all of the following phpDocumentator tags:

@access
@author
@copyright
@deprecated
@example
@ignore
@internal
@link
@param
@return
@see
@since
@tutorial
@version
inline {@internal}}
inline {@inheritdoc}}
inline {@link}}

An example class illustrating proper comments:

/**
* Class to print <Message> <Name>
* @author NeilC
*/
class HelloWorld {
/**
* First part of message returned by {@link display()}
*
* @var string
* @access public
*/
var $text = 'Hello ';
/**
* Returns HTML blink tag containing the value
* of $this->text and the name sent to the method
*
* @param string $name Name to display, defaults to John
* @return string
* @access public
*/
function display($name = 'John') {
echo '<blink>'.$this->text.$name.'</blink>';
return true;
}
}

Variable types

Variable types for use in DocBlocks:

Type Description
mixed A variable with undefined (or multiple) type.
integer Integer type variable (whole number).
float Float type (point number).
boolean Logical type (true or false).
string String type (any value in “” or ”).
array Array type.
object Object type.
resource Resource type (returned by for example mysql_connect()).

Remember that when you specify the type as mixed, you should indicate whether it is unknown, or what the possible types are.

Including files

When including files with classes or libraries, use only and always the require_once function.

In making includes in the app folder, use the bootstrap to call general functions and use vendor() instead of require_once(). All included files should then be placed in the vendors folder.

Example call in the /core/bootstrap.php
vendor('functions');

Naming conventions

Functions

Function names should be written in camelBack?, for example:

function longFunctionName() {
}

For functions that are used as controller actions and views pages, use underscores to break words and all lower caps. Example:

function long_function_name() {
}

Classes

Class names should be written in CamelCase, for example:

class ExampleClass {
}

Variables

Variable names should be as descriptive as possible, but also as short as possible. Normal variables should start with a lowercase letter, and should be written in camelBack in case of multiple words. Variables containing objects should start with a capital letter, and in some way associate to the class the variable is an object of. Example:

$x = 123;
$blogPosts = array();
$Dispatcher = new Dispatcher();

Member visibility

In addition to using PHP5′s private and protected keywords for methods or variables, a protected method or variable name should start with a single underscore (“_”). Example:

class A {
var _iAmAProtectedVariable;
function _iAmAProtectedMethod() {
}
}

A private method or variable name should start with double underscore (“__”). Example:


class A {
var __iAmAPrivateVariable;
function __iAmAPrivateMethod() {
}
}

Files

File names should be created with lower case. If a file name consists of multiple words, they should be divided by an underscore character, for example:

long_file_name.php

Constants

Constants should be defined in capital letters:

define('CONSTANT', 1);

If a constant name consists of multiple words, they should be separated by an underscore character, for example:

define('LONG_NAMED_CONSTANT', 2);

All global constants should be declared in the /config/bootstrap.php

SQL Guidelines

All aliases, table names and field names should be surrounded by back ticks e.g:

$this->find(array('`Post`.`status`' => 'Enabled'),'`Post`.`title`','`Post`.`created` DESC');

Capitalize keywords, break lines on keywords and use CakePHP table aliases to keep the code clean


$this->query("
SELECT *
FROM `posts` AS `Post`
LEFT JOIN `comments` AS `Comment` ON `Post`.`id` = `Comment`.`post_id`
WHERE `Post`.`status` = 'Enabled'
AND `Comment`.`status` = 'Enabled'
ORDER BY `Post`.`created`
LIMIT 10
");

PHP code in views

Try not to echo out markup, open PHP tags and echo content into markup wherever possible, this facilitates markup maintenance and modification by developers that are not familiar with PHP syntax and can therefore just ignore any PHP code, while still being able to edit the HTML.

Whenever you close PHP tags within a control stucture, always use the colon, end-control-structure syntax, so that it is clearer which control structure you are closing, e.g.

<?php if(....) : ?>
<p>html markup here</p>
<?php endif; ?>

rather than this

<?php if(....){ ?>
<p>html markup here</p>
<?php } ?>

If you need to nest control structures, always use a separate line for each, e.g.

<?php foreach ($a as $b): ?>
<?php if($b == $c): ?>
<p>html markup here</p>
<?php endif; ?>
<?php endforeach; ?>

not the following:

<?php foreach ($a as $b): if($b == $c): ?>
<p>html markup here</p>
<?php endif; endforeach; ?>

Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot

Be the first to rate this post
Loading ... Loading ...

Comments are closed.