|
|
Project Coding Standards
These are general notes applied to Projects that I work on, the main
intent is to try and make the code maintainable over a long period of
time.
PHP Code
- Follow PEAR
Standards Which are (with slight additions):
- Indenting
- 4 spaces (Not tabs)
- Do not over indent
- Try and keep within 80 chars wide
Bad:
$ret = $this->callSomething(array('xxx' => 'yyyy',
'zzz' => 'aaaa' ....
Good
$ret = $this->callSomething(array(
'xxx' => 'yyyy',
'zzz' => 'aaaa' ....
));
- Control Structures
- If / else
- No short ifs (eg. always use brackets)
- do not use else if you have returned or used break; within
a block.
if ((condition) || (condition2)) {
statement;
statement;
} else {
statement;
}
if ((condition) || (condition2)) {
statement;
statement;
} elseif ((condition) || (condition2)) {
statement;
}
// for long if statements
if ((condition)
|| (condition2) //8 space indent
|| (condition2)
|| (condition2)
) { // closer and opener 4 space indented
statement;
statement;
}
- break out or return rather than nesting if statements
When inside methods or loops, use return or break, rather than have
heavily nested if blocks
for ($i = 0; $i < 100; $i++) {
if (!$x) {
break;
}
if ($x < 10) {
statement;
statement;
break;
}
......
}
function get($arg)
{
$do = DB_DataObject:;factory('xxxx');
if (!(int)$arg || !$do->get($arg)) {
return HTML_FlexyFramework::factory('Error/404', array('errors'=> .....);
}
.....
- Switch Case
- Method Calls
- No space between method name and ( and first paramenter
- space after each,
- avoid more than 2 arguments to a method (use named
arguments)
- dont over indent arguments
- commas after argument, not before
- extra space can be added before return assignment to
enhance readability
$ret = $this->callSomething($a, $b);
$ret = $this->callSomething(array(
'xxx' => 'yyyy',
'zzz' => 'aaaa',
));
$abcdefg = $this->find();
$xxx = $this->fetch();
- Method Definitions
- Class Definitions
- Comments
- Include / Require
- PHP Code tags
- Do not use short tags (<?)
- Do not add the closing tag to files (?>) as it often can
break sessions
- Naming Conventions
- Classes
- use Caps_First with _ between names. (exceptions may
occur when part of the name relates to an extenal object - eg. a
database table)
- Good: Some_MyProject, Some_Project_Driver
- Bad: SomeProjectThatWorks, SomeProject_ProjectDriver
- Underscore heirachy should relate to extends
pattern where feasible
- Fred_Driver_Postgres extends Fred_Driver
- Libraries should always use a type prefix (eg.
HTML_/Net_/DB_ etc.)
- Projects should always have a non-generic name, and all
classes should extend that (see later)
- Functions
- Methods / Variables
- Always use studlyCaps with first letter lower, and latter
ones upper case.
- Good: someMethod(), $this->someVar;
- Bad: some_method(), SomeMethod(),
$this->some_var
- Prefix private methods with underscore (these may use _
in names as well.
- _my_private_method()
- $this->_my_private_var;
- Avoid pass-by-reference, unless absolutely necessary.
- Constants
- Built in constants should use lower case
- User Defined constants should be associated with a class
and all uppercase
- Global Variables
- Should always be associated with a class
- Should not be accessed from outside the owning class.
- Should be initialized when the class is loaded (in global
space)
- File Formats
- Should use UNIX line endings (\n) not (\r\n)
- Class inheritance
- Avoid to many levels of extends, in general code (above 3
should be extremely rare, and well justified.)
- Require / Lazy loading
- Utilize Lazy loading, avoid requiring files at the start of
each class/page file.
- Avoid long lists of require_once's at the top of each file.
- Avoid assuming that a class is loaded, help the end user out by
explicitly saying where some class comes from.
- Mixing PHP + HTML/Data
- Method Arguments
- Maximum of 3, over that, use named arguments array.
- Prefered Max is 2 arguments.
- Avoid pass by reference, unless absolutely necessary (it makes
code more difficult to follow) - return arrays or associative arrays.
- XML / HTML
- unless processing huge XML files, use the DOM extensions
rather than XML_Tree/XML_Parser.
- DataObjects:
- FlexyFramework
- Implement and use Page base classes
- A project one (non-authenticated) eg. MyProject extends
HTML_FlexyFramework2_Page
- A authenticated one, eg. MyProject_Authenticated extends
MyProject
- Page Classes should avoid deep directory trees:
- MyProject_Products_Search_Edit
(MyProject/Products/Search/Edit.php) == BAD
- MyProject_ProductsEdit (MyProject/ProductEdit.php) == GOOD.
- Page Constructors
- __construct or class constructors should not be used (it
makes the code to difficult to follow)
- Unused shared base classes (eg. MyProject_SomePage extends
MyProject_SomePageBase)
- Avoid these, merge the code into an existing class (either
the project one or a relivant page)
- Avoid calling parent::get() or parent::post(), make explicite
methods for actions, and call them specificily in child classes. (This
enables top level get/post to return 404 errors on pages not found)
- Do not use the modules toolkit - it was a bad idea, and is only ther for Backwards compatibility
(you should write your own project based loadModules routine, that loads any modules you intend to use)
- Do not make error handling a module Errors should be handled
with flags (or values with context data, not messages) and be part of
the page template
- Emailing
- Errors
- Do not use @ to suppress errors unless absolutly necessary.
- in PHP4
- use PEAR::raiseError(), lazy loaded.
- consider outputtting debuging information via
trigger_error(E_USER_WARNING) (when debugging is turned on.)
- in PHP5,
- trigger_errror() is for programming errors / debug warnings.
- Exceptions for everything else (Probably PEAR_Exceptions)
- Try and catch all exceptions where they are thrown. - try
and avoid global catchalls.
- use function arguments to determine if Exceptions should be
converted to return values, or run
HTML_FlexyFramework::run('error',array('errors'=>
array('problem_with_xxx'=>true)));
- Constants
- Should not be used as configuration variables
- Normal usage should be to assist in the readability of code,
normally in cases where a set of numerical states can be represented by
a textural word (eg. SMTP_STATE_READY_TO_SEND = 1)
- Naming should follow PEAR standards (eg. with class name
prefixed - or in PHP5 just use class constants.)
- Configuration
- Most configuration is automatically detected by the Framework,
however other configuration settings may originate from
- Read Access
- Sessions
- Debugging
- at present the recommendation is to use a debug flag on a
class, and trigger_error with E_USER_WARNING. this can be caught by the
error handler if neccessary and reformated.
Javascript
General Coding (PHP / js)
- Avoid mapping names (especially databases columns to other names)
- BAD : this.tbx0 = document.getElementById('username');
- GOOD : this.username = document.getElementById('username');
- EVEN BETTER this.elements['username'] =
document.getElementById('username');
- This can then be automated by for[each] loops...
HTML (and Flexy Templates)
XUL
- do not use commandset/command, use oncommand with javascript call.
CSS
Add a comment (requires javascript!)
|
|