RSS
 

Coding Standards

This is supposed to be a summary of guidelines addressing (web)development.
Especially if multiple team members are working on the same code – but also if one single developer wants to have clean reusable code throughout his application.

Overview

This is mainly all covered in php-fig-rectified/fig-rectified-standards coding standards.
This also extends the standards of CakePHP as well as other resources. There are some differences – especially compared to coding standards like PEAR etc.

In the past some groups arose around that very same matter. Namely FIG and phptherightway.com.
Those ideas are almost completely valid and inherited below.
There are same major and minor issues with some ideas though that cannot be accepted in the form it has been made a modern "coding standard".

The major differences (especially towards PSR-2) are outlined beforehand pretty quick:

  • Tabs vs spaces: Only tabs are valid indentation.
  • Consistency in {}: Opening braces always on the same line, for control structures, functions and classes

Common

The language is English, both in function/variable names and in comments.

All code lines should be indented properly – this improves readability.
Use one tab as indent – good IDEs can transform them into (soft) spaces (as many as you find suitable).

[‘] or ["]??
Usually I use the normal [‘] – as ["] is for html attributes.
No variables inside strings – they are splitted like that:

echo 'A string with '.$someVariable.' and '.SOME_CONSTANT.'!';
echo '<a href="http://example.org" title="' . $title . '">Link</a>';

This increases readability most of the time.
The other case I use ["] is inside query functions of the database object, where [‘] is needed to escape strings.

Note: The Cake Core usually puts spaces between . separated strings like $value . $value2 – you should do that this way, as well. In the past I did not always respect that, but I started to migrate my code according to the Cake conventions.

Important Definitions

CamelCase: all the words have a capital – no whitespaces

camelBack: first word has a minuscule, all following ones have a capitel

snake_case: all lowercase and separated by an underscore

function: normal php function (for itself)

method: function INSIDE a class – usually the case in CakePHP

object: instantiated class

PHP

The { open bracket is in the same line of the function name (as shown below in the "function edit()").
Same goes for classes, if/else statements, while-loops etc.

Objects are in CamelCase (and should represent the class name):

App::uses('FileUtil', 'PluginName.Utility');
$FileUtil = new FileUtil(...)

Note: =& is not necessary anymore in PHP5 (automatically assigned by reference).

Also note: After a , [Comma] there’s usually a space.

Methods and variables usually are in camelBack:

public function xyzAbc($someVar = null) {
	...
	return $someOtherVar;
}

Note: this is not true for (prefixed) controller actions. They are actually an url link (can be accessed trough …/your_site/controller_name/method_action/…).
E.g. admin_index_all(): called per url /admin/controller/index_all/ (instead of /admin/controller/indexAll() which is not completely lowercase).

Also note that methods must either be declared public or protected (never private). Same goes for class attributes.

Dont’ use magic numbers (like a literal 3) directly in the code. Try to use constants for them as they are more verbose and tell the developer right away what they stand for.

MYSQL

All tables start with a primary key (integer) called "id", unsigned, auto-increment:

`id` int(10) unsigned NOT NULL

or (if UUIDs are used instead of AIIDs) with a char36 (char):

`id` char(36) NOT NULL

Same for the foreign keys.

The field names are lowercase – and multiple words separated through underscores:
"some_field_id" or "date_checkout"

Numeric fields (INT, TINYINT etc) can be "unsigned", if there won’t be any negative values, primary and foreign keys must be (they can never be negative).

Usabiltity:
I started to group certain tables.
In my opinion it can be quite a difficult task to keep track of the tables belonging together (especially with using HATBM naming rule "alphabetic order").
So I now group them by the logical "main" table. The main table will be the first word (singular! + [_]) of the other tables.

Example "role":

roles
role_xyz (roles HasMany xyz)
role_users (HABTM between roles and users)
role_applications (HABTM between roles and users)

As you can see, here are two relations that have the same 2 tables, all of them can be found under "role…". If you would try to sort them the cake way, you would have a naming conflict as well as (in most cases) difficulties to find them due to different first letters (roles, xyz, ..).

The naming conflict results out of the convention to have to name both "roles_users".
Both tables have not that much to do which each other though, as the first one consists of the current roles-user-relation, the second one has some information about users applying to roles (with apply_date, approval_status (which could be -1 = dissapproved), approved_by (admin userid) and so on). But still, they all have the roles table in common. If you look for them it would not be "applications", "applications_roles" or "xyz", but "role_…).

Example "snippet":

snippets
snippet_cats (snippets HasMany cats)
snippet_elements (snippets HasMany elements)
snippet_tags (HABTM between snippets and tags)

It is more logical to always group them all under the main table – in this case under "snippets".
Otherwise you find the HATBM table for "xyzsnippets" under "tags_xyzsnippets" – but for "abcsnippets" it would be "abcsnippets_tags" – which (quite obvious) is not persuading at all.

HTML

All tags and attributes are lowercase.

JS

All functions are camelBack.

All style attributes have to be lowercase:

/* would not work properly: */
document.getElementById('xyz').style['Color'] = 'black';
/* it has to be: */
document.getElementById('xyz').style['color'] = 'black';

CSS

Definition:

class: .some-class-name
id: #some-id-to-an-element

both with lowercase characters (although classes are not case-sensitive, id’s are!),
the separator is minus [-]. You can use underscore [_] if it makes the separation of the identifier and the record id easier. E.g. "my-id_33". It will become necessary to do so if you use UUIDs (which contain minus chars).

Note: ids should be unique on the current page – so don’t use them for iterating elements. In general all styling should be class based. Ids are often abused for that. But
they usually serve the purpose of being identifiable via JS. So they should ideally be mainly used for dynamic JS stuff.

Do not name the fields after their style, but after the function/meaning – as the style can change and will result in things like ".red { color: yellow;}"

Good Example:

span.success {
	/* color: green; // not any more */
	color: dark-green;
}
div.important {
	/* font-weight: bold; // not any more */
	font-size: 14px;
}

Use Inheritance. And – to avoid, that any added style for other pages affect the current one, declare the inheritance the following way:

div.report {
	margin-left: 12px;
	background-color: #E6E7E8;
}
div.report table {
	width: 330px;
	border-collapse: separate;
}
div.report table th {
	font-weight: bold;
}
div.report table td.descr {
	text-align: center;
}

Now, the .descr class on the td of this table does not get screwed up, if there is any other .descr in the stylesheets.

Code Documentation

Especially inline-documentation is quite important. Not only for others, but also for yourself to be able to understand what you did some months/years ago.

All comments should in a clear way describe what is going on.

PHP:

Use /* */ for longer comments and // Some comment for one-line comments (usually right above the code).
I recommend to always add a space after // as without that space it usually stands for some line of code commented out – which can lead to misunderstandings.

You should also comment all your methods/functions – take a look at the different tags available.

Example:

/**
 * Method description here
 * 
 * @param string $var Dirty name,
 * @return string Cleaned name.
 */
public function someFunction($var) {
    ...	
    // Now we need to shift the array
    $var = array_shift($var);
    ...
    return $var;
}

With a good php editor (like PHPDesigner 200x), you are able to use these method comments while programming (as it pops up on each method/function as soon as you click inside the brackets (even beyond the current page – as the editor looks through your complete app directory)

All functions/method should have @param (if applicable) and @return statements. Only constructors/deconstructors don’t have @return statements.
See book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html#commenting-code for details

JS

Use /* */ for comments (usually above the code).
Although // would be allowed as well – this is (as in PHP) usually code commented out.

CSS

In CSS documents there is just the /* */ to comment your code (usually above).
You should built some kind of hierarchy with them – if you have any.

Lets say we have a global css file (default site wide css) and another "specific controller" css file.
Then you could sort them like this (the action level is not really necessary, but shows what could be done):

/***** POSTS CONTROLLER *****/
/*** View Action ***/
div.report {
	margin-left:12px;
	background-color:#E6E7E8;
}
/* the table for the reports */
div.report table {
	width:330px;
	border-collapse: separate;
}
div.report table td.descr {
	text-align: center;
}
...

Changes for PHP5.4 and/or CakePHP3.x

It seems the short open tags are becoming more popular in the view layer: <?= $somevar ?> is now considered valid PHP templating.
I am not yet sure if I would want to adopt this. But it might make sense for new PHP5.4+ projects – IF the view layer is clean enough to allow
such an approach without too many <? and <?php mixins. Because otherwise I would rather keep it consistent and verbose.

Details here.

Appendix

The PEAR Package contains some tips about "best practices".

Leave a Reply

Tip:
If you need to post a piece of code use {code type=php}...{/code}.
Allowed types are "php", "mysql", "html", "js", "css".

Please do not escape your post (leave all ", <, > and & as they are!). If you have encoded characters and need to reverse ("decode") it, you can do that here!
 

 
  1. iNaD

    December 20, 2010 at 20:46

    Hi guys,
    it’s always interesting to see how others think about coding guidelines / standards.
    Personally I like it more if the { open bracket is in a new line. For me it’s a better overview, but everyone has to make his own decision I think?!
    But this is a nice introduction to new developers =]

     
  2. Mark

    December 21, 2010 at 00:00

    I hate it!
    It’s on of the things that really upsets me about other code if the {} brackets are not correctly set^^
    everything is debatable, but not this, in my opinion.
    grrrr

     
  3. Whootland

    January 25, 2011 at 20:52

    I agree with iNaD, having the { open bracket on a new line is a lot cleaner. This way you will have the open and close bracket on the same column (position vertically) and this makes it easier to see what code block it belongs to. If you put it on the same line it (in my opinion) looks crooked. Especialy when you have a lot of nesting with many ifs/foreaches/etc.

    I wonder what your reasons are for doing this, because you didn’t post an explanation for this opinion. Just wondering…

    Great blog by the way!

     
  4. Mark

    January 26, 2011 at 00:27

    You are right
    I covered it only briefly in
    http://www.dereuromark.de/2011/01/16/coding-standards-in-php/

    As stated, the readability increases dramatically (indentation is the keyword here). Your argument was strong when programmers didn’t use IDEs but pure txt-editors. But nowadays with a proper IDE you get the opening and closing bracket highlighted(!). That + the intendation is enough to make any code readable very beautifully.
    And the main disadvantage of the new line style (did I already say that i hate it?^^) is that it triples(!!!) in most cases the length of the function. Totally nonsense in my opionion. Some (usually not very well written) functions can even extend the height of the screen, and there you are happy if no nonsense-lines are added 🙂

    Example:

    (good)

    # 7 lines
    if ($varX) {
    	$this->foo();
    } elseif($varY) {
    	$this->bar();	
    } else {
    	$this->end();	
    }

    (bad)

    # 12 lines
    if ($varX)
    {
    	$this->foo();
    }
    elseif ($varY)
    {
    	$this->bar();	
    }
    else 
    {
    	$this->end();	
    }

    To emphasize for all those souls that are lost on the wrong path here:
    The closing bracket is on the same vertical alignment as the condition/text that started it.
    Thats about all that is needed.