Annex 1. Coding Standards

We would like to keep a strict coding standard based on our experiences with other frameworks and CMS' to ensure when other developers read our source, we present code to be readable, logical and well explained.

A. Arrays

Arrays should be properly tabbed when appropiate. the closing parenthesis should be in line with the last value. The following shows valid examples.

Figure 1. Arrays
$array1 = array('i', 'am', 'inline');

$array2 = array(
	'user_id' 		=> 123,
	'user_name'		=> 'Chris',
	'user_created'	=> '2012-01-30');
	
$array3 = array(
	'i', 		'am', 	'a', 	
	'really', 	'long',	'lorem', 
	'ipsum', 	'dolor');

Figure 1 also shows that we prefer single quotes over double or "

B. Curly Braces

Opening curly braces or { should not be in it's own line. All closing curly braces or } must have a line break after. The exceptions are the closing curly before an else if or a try...catch. Curly braces should be used in all if statements and loops, even if it is a one line conditional. The following shows some valid examples.

Figure 2. Curly Braces
public function getZebra($number) {
	if($number % 3 == 1) {
		return 1;
	} else if($number % 3 == 2) {
		return 2;
	}
	
	for($i = 0; $i < $number; $i++) {
		if($i % $number === 0) {
			break;
		}
	}
	
	return $i;
}
Figure 3. Bad Curly Braces
public function getZebra($number) 
{
	if($number % 3 == 1) return 1;
	elseif($number % 3 == 2) return 2;
	
	for($i = 0; $i < $number; $i++)
		if($i % $number === 0) 
		{
			break;
		}
	return $i;
}
Figure 3 shows a bad example of an else if as well. The syntax elseif is valid when using PHP templating as in <?php elseif($isValid): ?>.

C. Class Structure

When creating a class, we doc categorize different class elements as a guide to know where to put things like constants, properties and methods as well as help other developers find things within the class faster.

Figure 4. Class Structure
class My_Class extends Eden_Class {
	/* Constants
	-------------------------------*/
	/* Public Properties
	-------------------------------*/
	/* Protected Properties
	-------------------------------*/
	/* Private Properties
	-------------------------------*/
	/* Magic
	-------------------------------*/
	/* Public Methods
	-------------------------------*/
	/* Protected Methods
	-------------------------------*/
	/* Private Methods
	-------------------------------*/
}

D. Java Doc

Every class, public method and function should have a respective Java Doc defined before the definition.

Figure 5. Java Doc
/**
 * Returns the squared version of the given number
 *
 * @param number
 * @return number
 */
public function squared($number) {
	return $number * $number;
}

The example above shows us how to declare a simple Java Doc. We practice only using the @param and the @return attributes. Both attributes should follow with a data type, exact value or a representation of an object

Valid Data Types
  • null
  • int
  • float
  • number
  • string
  • array
  • bool
  • [CLASS NAME]
  • this

Although most of the data types defined above are self-explanitory, the last two may need some explanation. [CLASS_NAME] refers to a name of a class. In Figure 1, we declared a class called My_Class. We can use this class name as a data type in @param or @return as in @param My_Class. this refers to the class the following method is defined in.

It is possible to have multiple parameters in a method. For this you just need to declare more than one @param attribute. If your @param or @return needs more explaination, you can write a small description after the data type. It is also possible that a parameter can accept more than one data type. For these cases we simply add a "pipe" symbol or | in between each type. It is also possible that the last argument could be virtually infinite. For these cases we want to wrap optional arguments with a box and infinite possibilities with a .. as in string[,string..]. The example below shows some examples of these cases.

Figure 6. Param Examples
/**
 * Something explaining the method
 *
 * @param number the user id
 * @param string[,string..] a list of strings to concatenate
 * @param array|string|null the query parameters
 * @param false[,int[,array..]] a list of arrays
 * @return number
 */

E. Naming Conventions

Deciding a name of a property or method should briefly explain what that is.

Constants

Constants should be all uppercase with underscores or _ to separate each word. When writing classes, we should use constants for any string or value that does not change in the class. This makes it easier to modify values when they actually do need to change.

const GOOGLE_GDATA_HEADER = 'Gdata: 2';
Class Names

Similar to constants however the first letter of each word should be capitalized.

class My_Epic_User {}
Method Names

Method names should be camel cased; starts with a lowercase character and capitalize the first letter of each following word. Method names should always start with a verb. You should always consider your verbs to be either get or set as most methods can fall in either of the two. Of course methods like creating an event or updating a user could start with create, add, update, remove.

public function setName('Chris') {}

public function getUserCreated() {}

public function updateRow($row) {}

public function removePost($postId) {}

Having a method just called set, get or any verb can be valid if your class is based off a model.

class User {
	public function set('name', 'Chris') {} //would mean set user name to chris
}
Property Names

Property names, like methods should be camel cased. Property names should always start with a noun. The exception is if a property is a boolean.

$userCreated 	= date();
$postTitle 		= 'Lorem Ipsum';
$isValid 		= true;

F. Simplification

We should always think about the developers reading our code. Simplifying code will save time in the end also whenever you need to go back and troubleshoot an error.

Example 1
if($valid) {
	return 1;
} else {
	return 0;
}

could be simplified to

if($valid) {
	return 1;
}

return 0;
Example 2
if($valid) {
	return 1;
} else {
	if(is_null($valid)) {
		return NULL;
	}
}

return 0;

could be simplified to

if($valid) {
	return 1;
} else if(is_null($valid)) {
	return NULL;
}

return 0;

Simplifying doesn't explicitly mean shortening code; it could also mean de-leveling code.

Example 3
foreach($posts as $post) {
	if($post['id'] != 0) {
		$post['created'] = strtotime($post['created']);
		$valid[] = $post;
	}
}

Example 3 shows how action code is wrapped in 3 levels of tabs. It could be simplified to

foreach($posts as $post) {
	if($post['id'] == 0) {
		continue;
	}
	
	$post['created'] = strtotime($post['created']);
	$valid[] = $post;
}

© 2012 Openovate Labs. All rights reserved.