Powered by MediaWiki
Personal tools

Standard Coding Guidelines

From b2evolution manual

Jump to: navigation, search

This manual page is outdated. NEW PAGE: Standard Coding Guidelines in b2evolution v5+.

Contents

[edit] General guidelines

  • Please log major changes in docs/changes.html

[edit] PHP guidelines

[edit] Inline code documentation

Technical documentation is automatically generated by extracting comments form the source code, using phpDocumentor.

To document functions, objects, variables and other code elements, please add documentation to the source code in phpDocumentor format, which is actually very close to Javadoc.

Anyhow, even if you don't want to follow Javadoc format, do not restrain from adding comments to your code as well as to the existing code you're currently trying to understand.

[edit] Editor Settings

Tabs vs. Spaces: In order to make this as simple as possible, we will be using tabs, not spaces. Feel free to set how many spaces your editor uses when it displays tabs, but make sure that when you save the file, it's saving tabs and not spaces. Note: Prefered tab length is 2. This will affect alignment of end-of-line comments. If you do not use a tab length of 2, please do not use tabs after the initial line indentation.

Line endings: CVS will auto-convert line endings depending on the platform you use. So this should generally not be an issue. However, please make sure that if you are developing on Windows you use Windows line endings and if you are developing on Linux you use Linux line endings. If you screw up, CVS will screw up too.

[edit] Where to put the braces

This one is a bit of a holy war, but we're going to use a style that can be summed up in one sentence: Braces always go on their own line. The closing brace should also always be at the same column as the corresponding opening brace.

Examples:

	if ( condition ) 
	{	// This is a good place for a comment!

		while ( condition2 )
		{	// This is a good place for a comment!

			...
		}
	}
	else 
	{	// This is a good place for a comment!

		...
	}

	for ( $i = 0; $i < $size; $i++ ) 
	{	// This is a good place for a comment!

		...
	}
		
	while ( condition ) 
	{	// This is a good place for a comment!

		...
	}
	
	function do_stuff() 
	{	// This is a good place for a comment!

		...
	}

[edit] Where to use spaces

Use spaces between tokens: This is another simple, easy step that helps keep code readable without much effort. Whenever you write an assignment, expression, etc.. Always leave one space between the tokens. Basically, write code as if it was English, with the exception of brackets. Put spaces between variable names and operators. Don't put spaces just before a comma or a semicolon. This is best shown with a few examples.

// instead of:
$i=0;
// please write:
$i = 0;

// instead of:
if($i<7) ...
// please write:
if( $i < 7 ) ...
		
// instead of:
if ( ($i < 7)&&($j < 8) ) ...
// please write (also note that unnecessary braces have been omitted):
if( $i < 7 && $j < 8 ) ...
		
// instead of:
do_stuff($i,"foo",$b);
// please write:
do_stuff( $i, 'foo', $b );
		
// instead of:
for($i=0; $i<$size; $i++) ...
// please write:
for( $i = 0; $i < $size; $i++ ) ... 
		
// instead of:
$i=($j < $size)?0:1;
// please write:
$i = $j < $size ? 0 : 1;

[edit] Operator precedence

Do you know the exact precedence of all the operators in PHP? Neither do I. Don't guess. Always make it obvious by using brackets to force the precedence of an equation so you know what it does.

Examples:

// what's the result? who knows?
$bool = $i < 7 && $j > 8 || $k == 4;
	
// now you can be certain what I'm doing here.
$bool = ( $i < 7 && $j > 8 ) || $k == 4;

[edit] Quoting strings

There are two different ways to quote strings in PHP - either with single quotes or with double quotes. The main difference is that the parser does variable interpolation in double-quoted strings, but not in single quoted strings. Because of this, you should always use single quotes unless you specifically need variable interpolation to be done on that string. This way, we can save the parser the trouble of parsing a bunch of strings where no interpolation needs to be done. Also, if you are using a string variable as part of a function call, you do not need to enclose that variable in quotes. Again, this will just make unnecessary work for the parser. Note, however, that all of the escape sequences that exist for double-quoted strings will not work with single-quoted strings. Be careful, and feel free to break this guideline if it's making your code harder to read.

Examples:

/* wrong */
$str = "This is a really long string with no variables for the parser to find.";
do_stuff("$str");
		
/* right */
$str = 'This is a really long string with no variables for the parser to find.';
do_stuff( $str );

/* wrong */
echo "This is one line.\r\nThis is another.";

/* right */
echo 'This is one line.'."\r\n".'This is another.'

/* wrong */
$str = 'Hello';
echo "Our \$str variable contains: [$str]";

/* right */
$str = 'Hello';
echo 'Our $str variable contains: ['.$str.']';

[edit] Variable names, Member names, Class names

  • Remember this is PHP, not Microsoft Visual C++. There is actually little value in naming variables something like strFullTitle . Something like full_title is definitely enough and much easier to read!
  • As an exception to the previous rule, we'll preferably prefix private or protected member variables of a class with an underscore as in _full_title. This serves as an easy reminder that the variable is not designed to be called in any other ways as in $this->_full_title .
  • You will also see underscores (_) being used within file names. This shows that the php page is not to be accessed directly but instead is to an inclusion to another php page.

include '_file.ext';

  • Class names should start with a capital, as in Book .
  • Variable names should be all lowercase, as in $title = 'A brand new day'; except when they are object references as in:

$a_Book = & new Book( 'A brand new day' );

  • When naming object references, always end their name with the name of the class as in $a_Book or $another_Book instead of Book_to_read for example. This allows to easily search & find all calls to a given method of a given class. You could for exampel easily search on this string: "Book->get_title(" .
  • If you are creating a variable to contain the value of a variable inside a class, we would name it like so $Obj_var, where "Obj" is the name of the class and "var" is the name of the variable, Eg.

$Item_title = $Item->title; // not $Items_title = $Item->title;

[edit] Other

  • Use require instead of include. Use require_once when including functions and global definitions.
  • Whenever you use an user interface string containing English words, enclose it in T_( ) to enable Translation when users run b2evo in another language. Please look at some examples in the code, especially printf / sprintf examples. The marked strings will be automatically extracted for translation (here is more info about how translators work).
  • Use Perl compatible regular expressions (preg_ functions) instead of POSIX. (better performance).
  • Do not use the function mb_detect_encoding(). It is not reliable and sometimes detects the wrong encoding. Helpful global variables are e. g. $current_encoding, $evo_charset and $io_charset.
  • Do not use PHP short opening tags ( <? ). Always use <?php as some users run on hosts not supporting the short tags.
/* wrong */
<p><?=$text?></p>

/* right */
<p><?php echo $text; ?></p>
  • When cycling through an array, never include the count function inside the loop's condition. Make a variable to hold the result instead. Otherwise for each cycle of the loop, the size of the array will be re-calculated causing your program to become quite slow.
/* wrong */
for ( $i = 0; $i < count( $myArray ); $i++ )
{
   // Code
}

/* right */
$s = count( $myArray );
for ( $i = 0; $i < $s; $i++ )
{
   // Code
}
  • When commenting code always include a space between the comment characters and the comment text.
/* wrong */
//My comment

/* right */
// My comment
  • In PHP it is perfectly normal to use: breaks within a for loop, multiple returns in a function, and dies and exits within your code.

[edit] SQL Guidelines

[edit] Escape input

Always use $DB->quote() or $DB->escape() on variables, that come from an untrusted source, which includes the user, of course!

[edit] Identing is useful for SQL too!

Don't write

UPDATE table SET field = value WHERE field = condition
but:
UPDATE table 
   SET field = value
 WHERE field = condition

[edit] Specifiying field names

  • Never use an INSERT INTO x VALUES( ... ).
  • Always specify which fields you act upon and in which order.
  • Also if you really want all fields from a table, you can write SELECT * but you must address the fields by their name in PHP.

Keep in mind that tables change over time. New fields can get added. Others can get suppressed. Some can get reordered. Different upgrade paths may lead to different field orders accross users!

Quality and maintainance require explicit field naming in all SQL queries. Assuming a particular field order at any time is suicidal!

[edit] Other

  • All SQL statements should be compatible with MySQL 4.1 (since b2evolution version 3.3; MySQL 3.23 *no subqueries* in older b2evolution versions).
  • When you create a new table, take special care of the installation process. You need to handle new installations but also upgrades. Try to understand how the upgrade process works, especially the db version number checking, before adding your code just anywhere.

Parts of this document inspired by phpBB