Table of Contents
__toString and
PrintableArrayAccess and
MappableThe coding standards are a set of rules and restrictions when writing code for the Web:Extend framework. Please follow them when you intend to submit code or patches.
All code must be licensed under the
LGPL
2.1 or later, or any other compatible license. The header of
the file must contain the license terms, the name of the product this
applies to (for example: a module or a file), and the years when the
license was in use along with the author's name. For example a file
created by us in 2006 will have the following line 2 years later:
Copyright (c) 2006-2008 Dev:Extend.
Unless stated otherwise, the submitter keeps copyright over his own code.
A PHP file must begin with the following lines, with the exception of unit test files.
<?php /* PRODUCT Copyright (c) YEARS AUTHORS LICENSE TERMS OR LINK TO THE LICENSE */ if (!defined('ALLOW_INCLUSION')) die;
The test on ALLOW_INCLUSION prevents the
execution of the code in the file if it was loaded directly in a web
browser. The code will only be executed if it is included from a
bootstrap file.
You must not close the PHP tag using ?>
at the end of the file. Closing the tag can introduce bugs into the
code if you put too many line breaks after it. The reason for this is
because PHP will send the subsequent line breaks to the browser,
preventing you from sending cookies at a later time.
Use the http://example.com/ URL when you
need to give an URL in an example. This domain name is reserved for
this specific use.
The naming conventions are the same for everything but constants.
They should be named using the camel convention. The first letter must be in lowercase. For example:
<?php
$iReturnedInteger = myPrintFunction();
Variables should be prefixed by the first letter of their
type. For example, all integers must begin by i.
Since PHP is loosely typed, we have introduced the
mixed type by convention to indicate that the
variable can contain different types. With one exception, if a
variable can hold multiple types then it is a
mixed variable.
The only exception to this rule is when you have a
Printable or Mappable object.
Printable objects can be considered either as a
string or as an object; Mappable objects can be
considered either as an array or as an object. For example, if you
write a method accepting both a string or a
Printable object as parameter, the parameter is
of the type string.
The following table indexes all existing types:
Table 1.1. List of variable types
| Type | Prefix |
|---|---|
| Boolean | b |
| Exception object | e |
| Float | f |
| Integer | i |
| Mixed | m |
| Object | o |
| Resource | r |
| String | s |
Sometimes it makes sense to use the variable name
$i in a for loop. However,
it never makes sense to name another variable $j
in another loop inside the first. If you need two variables, name
them properly.
Constants should always be all-uppercase, with underscores to separate words. Prefix constant names with the uppercased name of the module they are a part of (if applicable).
Avoid using global variables. The global
keyword and the $GLOBALS array are forbidden.
In the case you really, really must use a global variable, make sure
you unset it after using it so that no cruft remains when including
the file.
Do not refactorise to death. It's OK to have the exact same code in two different classes of the framework. Do not try to refactor it before there is at least 3 instances of the same code.
It also doesn't necessarily make sense to refactor duplicate code when this code only spans 2 or 3 lines, unless it is used virtually everywhere in the framework.
Code must be documented using comments.
There is two types of comments: docComments and inline comments. The first is a block of comments before a function, method, class, or property used to describe it. Inline comments are comments present inside a function.
DocComments are mandatory. They are used to build the API and thus need to be correctly written and explain properly the purpose of the item they document and the different uses for them.
<?php /** Example docComment. */
Inline comments are completely optional. In fact, they should only be used if the PHP code isn't strictly obvious. Inline comments ensure that when you come back to your code, you will understand it even if the code's purpose isn't intuitive. Use them wisely, too many inline comments is as bad as no inline comments for a complex code. Do not assume developers are stupid when you write them. On a related note, if you find your code is too hard to explain, you might consider rewriting it.
<?php
// Example inline comment
Do not use /* */ or # when
writing comments.
Prefer using protected instead of
private. Never try to guess that nobody will ever
need to extend your classes. When the time comes and someone actually
need it, they won't be able anymore.
Never use the __toString method. The reason
for this restriction is that throwing an exception in a
__toString method results in a fatal error.
Instead, use the Printable interface and the
toString method. Most methods in the framework
accept Printable objects for string parameters.
Beware when using ArrayAccess.
ArrayAccess objects are not usable in PHP's array
functions and behave unexpectedly when you use them with array
operators. When you need to represent an array using an object, you
should implement the Mappable interface. This
interface defines the method toArray used to convert
the object's data to an array. Most methods in the framework accept
Mappable objects for array parameters.
Use the SPL only where
it makes sense. While there's generally no problem using the
ArrayAccess or Iterator
interfaces, some of the classes can prove to be impractical. If your
project requires performance, you will want to avoid using
DirectoryIterator objects, for example. If you are
going to only use 2 methods of an SPL object, you might want to use
low level functions instead. Always make sure you understand the pros
and cons of the class you use.
Do not include files yourself. Autoload will load them for you.
The only time you'll need to include files is when using third-party libraries. In that case, you should use the require function instead of the various others.
Autoload expects filenames to match this pattern:
nameOfTheClass.class.php. Name your files
accordingly, and only include one class per file (except when you
want to prevent direct use of a class).
Use echo instead of print.
No specific reasons other than echo can be used with
multiple arguments that will get concatenated before being printed.
It's also better to use only one of the two for consistency.
Functions and methods in the framework should never return an
error code (unless it's the function's purpose to return it, as shown
in its name; for example getLastError).
When an error occurs, throw an exception. The developer will then have the choice to catch it or not, and will not have to ensure the data returned is actually data and not an error. If the developer doesn't catch an exception, an error page will be printed.
Arguments with a default value should always be last in the function's argument list. For example, this is good:
<?php function example($sProtocol, $sHost, $iPort = 80) { }
And this is bad:
<?php function example($iPort = 80, $sProtocol, $sHost) { }
Doing it improperly effectively make the default value useless.
When an array definition spans multiple lines, always add a comma at the end. This will help prevent parsing errors when adding another element in the array.
<?php
$aExample = array(
'protocol' => 'http',
'host' => 'example.org',
'port' => 80,
);
If a condition doesn't require curly braces, prefer writing it
on the front of the block, on the first if, to make
it easier to read. For example, this is good:
<?php if (condition1 || condition2) action1; elseif (condition3 && condition4) { action2; action3; } else { action4; action5; }
And this is bad:
<?php if (condition1 || condition2) { action1; action2; } elseif (condition3 && condition4) { action3; action4; } else action5;
Use operators instead of their textual equivalents (prefer
&& over and, for
example).
Do not use switch statements where it doesn't make sense. It only makes sense if you have a big number of conditions.
When possible, try to order the conditions so that it's easier to
read. If you use return or throw
at the end of a condition, you must not add a break
after (because it will never be reached). Try to ensure that every
condition has either a return,
throw or break. It makes things
much more readable.
Use single quotes instead of double quotes whenever possible.
When you have to use double quotes, you should not use a variable inside of them. Prefer a concatenation instead.