CODING GUIDELINES FOR BLUESHOES DEVELOPERS
------------------------------------------
@author andrej arn <andrej at blueshoes>
@author sam blume <sam at blueshoes>
@version 4.6 updated 2005-11-24
Basically...
we'd like to have a clean and professional, bug-free code.
Most people have different coding styles. And most think that
"the other style" is ugly. We don't want to force you changing
your style. Here is how we do it and like it:
o) We use capital letters for constants. e.g. define('CONSTANT', 1).
We also use the capital form of TRUE, FALSE and NULL.
This is true for PHP, note that javascript needs lowercase.
o) If a function is described to return bool, expect to get a real bool
(TRUE/FALSE) and not an int (0/1). So please code your functions and
methods that way.
o) Don't trust the return values from php methods. If they are stated
to return bool, they often return an int (0/1). So don't directly
return that from your functions, convert to (bool) if necessary.
o) Never ever use echo, print and die and the like inside your methods.
Use return.
o) this applies also for white spaces. if you start your file with anything
(an empty line) before the <?php tag, it will be sent to the client and
considered as output. This makes header() calls impossible (cookie,
session). The same applies for white spaces after the ?> tag. take care!
Even a newline is too much. This is a typical php newbie mistake.
o) Everything should be as os independant as possible. Including windows.
o) Make your code work with PHP version 4.3.0+ and 5.0.5+.
Don't support php3.
o) Make the php exam. Repeat it from time to time.
http://www.blueshoes.org/en/developer/syntax_exam/
o) Code object oriented. (PHP4)
o) Avoid setting vars in the global scope. If you need one, prefix it.
Example: $GLOBALS['_Bs_MyClass_MyVar'] = 'foo';
o) Avoid using things from global scope inside methods. Instead 'include'
them in the constructor.
o) Prefix classes with Bs_. This is a poor man's namespace.
o) Name your files like the classes: a class named 'Bs_Something' will
have the file name 'Bs_Something.class.php'.
o) One class per file.
o) References:
Don't return temporaries by reference.
function &foo() {
return new StdClass(); //this is wrong
return $ret = new StdClass(); //this is wrong too
//this is wrong too. (it works at least in php 4.4.1,
//but who knows, it's inconsistent, so please don't use it.)
return $ret =& new StdClass();
$ret =& new StdClass(); return $ret; //this is right
return FALSE; //this is wrong
return $ret = FALSE; //this is wrong
$ret = FALSE; return $ret; //this is right
$classOne =& new StdClass();
$classTwo =& new StdClass();
return (true) ? $classOne : $classTwo; //this is wrong
}
$object =& foo();
Don't pass temporaries by reference:
function foo(&$param) {}
foo(TRUE); //this is wrong
$param = TRUE; foo($param); //this is wrong
//this is wrong. (it works, but who knows, it's inconsistent,
//so please don't use it.)
foo(new StdClass);
$param =& new StdClass(); foo($param); //this is right
Also take care when encapsulating functions:
function foo() { return new StdClass(); }
function bar(&$param) {}
bar(foo()); //this is wrong
$object = foo(); bar($object); //this is right
When you create a new instance of a class, *always* do it by reference:
$object =& new SomeClass();
^---->this one
This is *important*, *important*, *important*!!. Trust me. if you don't,
you will after having strange bugs in your code and not finding them
for hours.
Also read http://www.zend.com/manual/language.oop.newref.php please.
o) Please use the same coding style as it is already used, if you can.
I know that changing your coding style is not easy if you're used to
something.
old: - a tab is 2 spaces
new: - a tab is a tab, we set it to the width of 2, but feel free to
configure your editor to show it as 3, 4, 8, whatever.
- A function is written like:
function something(param, param) {
//some code
}
- An if statement is written like:
if ($this == $that) {
} elseif ($this > $that) {
} else {
}
- Use spaces to separate:
$x .= $y . 'hello'; instead of $x.=$y.'hello';
exceptions are (for readability):
- $array = array('key'=>'value', 'key2'=>'value2');
- for ($i=1; $i<=10; $i++) {
- function myFunction($a='default', $b='foobar') {
o) Naming conventions:
- PHP itself is *very* inconsistent about the naming:
isset() but is_string() => underscore or not,
strtolower but bin2hex => to or 2,
create_function but str_shuffle => verb object, object verb,
strpos(haystack, needle) but in_array(needle, haystack) => order of param
so let's do it better.
- Use studly caps (first letter of each word capitalized (but not the
first one), otherwise lower case, no underscores) for vars, functions
(methods), lists, anything that needs a unique name.
class names go like 'Bs_SomeClass'.
vars/functions/objects/db-names are started lowercase, class
names/db-table names are started uppercase:
$someVarName instead of $some_var_name
someFunctionName() instead of some_function_name()
SomeObject instead of some_object
this especially also applies for short forms:
$someDbTable instead of $someDBTable
$someHtmlString instead of $someHTMLString
It is easier to read, and you can be sure how it was written. We think
it's better from experience. (An exception is the table field name/term
ID because of a naming convention.)
Often it is hard to decide if a word is made up of multiple words.
These words are considered being one word, not two, and thus have
no capital:
- username (not userName)
- password (not passWord)
- blueshoes (not blueShoes)
These words are considered being two words and thus have a capital:
- fileName (not filename)
- passPhraze (not passphraze)
- dateTime (not datetime)
A few other writings:
- email (not eMail or so, because someEmail will work while
someeMail or someEmail or someEMail would break the rules.)
Please avoid something like '$conn1' ('$conn2', '$conn3' ...) because
you cannot see if it was $conn1 or $connl. See what i mean? (one or
a small L, depending on the font)
- Don't use the fancy way pdf2html. It's kinda breaking the studly
caps rule. it would be pdf2Html and then it's not that readable
anymore because both '2' and 'H' are "upper case". So always use
pdfToHtml.
- Use verb object, not object verb. So makeObject(), not objectMake().
- If in doubt, use java syntax/style.
o) Learn the difference between == and === and != and !==. Read the manual
and check http://www.blueshoes.org/en/developer/php_cheat_sheet/
o) Passing by reference: Our code needs to be compatible with PHP 4 and 5.
PHP5 passes all objects by reference while PHP4 passes them by copy.
To make both versions behave the same way, do the following:
To pass by reference (99% of all cases):
function foo(&$theObject, $theInteger) {
...
}
foo($someObject, 5);
To pass by value (1% of all cases):
function foo($theObject, $theInteger) {
...
}
$copyOfObject = bs_clone($someObject);
foo($copyOfObject, 5);
o) Private vars and methods start with an underscore.
_foo is a private var, foo is a public var, _foo() is a private method
and foo() a public one.
o) In your classes, define all your public and private class vars using
var $something; or var $_something;
even if you don't set a default value. It will help maintaining the code.
o) Document while you code. Please document (phpdoc, like javadoc) your
functions, classes, methods, even class vars. I know that coders are
always in a hurry. But it will save a lot of time in the end!
It looks like this:
/**
* What the function does in one line.
* Here goes some more detailed description on 0-n lines, if needed.
* @access [public|static|pseudostatic]
* @param [string|int|double|bool|array|object|mixed] $paramName desc
* @return datatype description
* @throws [bs_exception|bool FALSE|NULL...]
* @see someFunction(), var someVar
* @todo description
* @since bs4.1, php4.3 (comma separated list)
* @status stable|experimental (if not set then considered stable)
* @pattern singleton|factory|mvc|observer|facade|...
*/
function something() {
}
For variables the @var keyword is used instead of @param:
/**
* Some internally used var.
* @access private
* @var bool $someStatus
* @see setSomeStatus()
*/
var $_someStatus = FALSE;
The description may include HTML, but please avoid it on the first line.
#@pattern singleton means that the constructor returns a reference
#to an already existing instance, if there is one.
o) Write ecg classes for your code. They will serve other coders
as examples and make the code more safe. Especially when it is
installed on other os'es, when new php/apache/mysql/... versions come
out etc. See naming for a definition of ecg.
The classes are in subfolders named 'ecg', for an example have a look
at core/util/ecg/Bs_String_PhpUnit.class.php
o) Don't eat junk food and never drink Red Bull at night. Pizza is ok. :)
o) Don't use underscores _ in databases (table names, field names).
They are reserved for relations (foreign key by naming convention).
Don't use the numbers 2, 3 and 4 inside of db table names. They are
reserved for the same reason.
o) Associative arrays are called 'hash', zero-based arrays are called
'vector'. Please use these terms. Undefined arrays are called 'array'.
o) Use the term 'function' for 'structured' procedural code. Use the term
'method' for functions inside classes. Don't use the terms 'procedures',
'subs', 'routines' etc.
sam: "methods are verbs, classes are substantives." :-)
o) When you return inside a switch or something, write the break too.
example:
switch ($x) {
case 'hello':
return TRUE;
break;
}
This way it will be harder for someone to 'implement' bugs into your code.
o) Avoid buggy code. For example if you're not 100% sure that a var is
an array, do is_array(), sizeOf($array) and such.
o) To be PHP4 compatible instead of using try-catch use the do-while(FALSE)
try-catch code, something like:
do { // try block
$isOk = someFunction();
if (!$isOk) break;
$isOk = otherFunction();
if (!$isOk) break;
//...
$isOk = TRUE; //everything worked
} while (FALSE);
if ($isOk) echo 'yeah';
o) Form your var declaration blocks etc in a nice way: (note the extra
spaces)
$a = 'hello';
$bbbb = 'world';
$cccccccc = 'foobar';
o) Mostly use foreach instead of while-list to loop arrays. See sam's
php-bench: http://www.blueshoes.org/en/developer/php_bench/
Note: there are also, and i like them (andrej)
while (list($k,) = each($a)) {
while (list(,$v) = each($a)) {
o) Magic_quotes_gpc was a good idea to prevent sql injection.
Unfortunately this feature can be turned on or off, was on in
previous PHP releases and is turned off by default now. This makes
the situation for libraries and released software a lot harder
which has to work with different configurations.
Check your php.ini, look for "magic_quotes_gpc". It
should be set to Off, not On. (magic_quotes_gpc = Off)
BlueShoes fixes this by checking magic_quotes_gpc, and if it is on,
it goes and undo'es the changes in _REQUEST, _GET, _POST and _COOKIE
see bs_undoMagicQuotes().
Note that there is other software around that does the opposite.
o) Make sure your code runs error free even if warnings and notices are
enabled.
o) Use the new superglobals (_GET, _POST etc), make sure your code works
if register_globals turned off. And we highly recommend to set
register_globals to off.
o) JavaScript classes are named like in php, for example
"Bs_FormFieldSelect.class.js". If it's a lib then it goes like
Bs_FormFieldSelect.lib.js. A lib is simply a collection of functions
for a special task, so not oo-code.
o) If you change something in code someone else maintains (and/or you're
not in the @author of the class or the function) then add your comments
along with the date and your name, example:
someCode(); //i did this because of that. 2002/10/16 --yourname
o) Don't add email addresses in plain text. Even the phpdoc comments in
the code get indexed, and thus could be spidered by email crawlers.
Please use "<user at domain dot com>" which makes it a bit harder to parse.
o) Naming (Glossary)
ecg ElectroCardioGram
In the code base you'll find many subdirectories with that
name. There are php code files that test our code. we
thought calling them just 'test' would not give them the
honor they deserve, and prolly someone would just delete
them. The ecg tests show a sysadmin very fast what's not
working (anymore) on his system, for example after the
installation or after a php upgrade or whatever.
whtml wysiwyg html. It's a mime type in blueshoes. It means that
the block [part] may be edited using wysiwyg. So it's not
xml compliant. A synonym would be "crappy html".
URL: (see Bs_Url.class.php and its methods)
scheme://user:pass@host:port/path?query#fragment
example: url https://bill:gates@order.blue-shoes.com:81/forms/
form.php?lang=fr&sid=456456#address
scheme = https
host = order.blue-shoes.com
port = 81
user = bill
pass = gates
path = /forms/form.php
query = lang=fr&sid=456456
fragment = address
domain = blue-shoes.com
directory = /forms/
file = form.php
xpv stands for xPointer vector. Match always returns an array, so xp
is always an array, maybe an empty one.
UID Unified ID.