-
Notifications
You must be signed in to change notification settings - Fork 22
Coding Style
This document describes coding style for the project and is loosely based on [http://pear.php.net/manual/en/standards.php PEAR coding standards].
== Style Enforcement == Conformance with these guidelines should be automated - run
make code
to run a phptidy tool to see what needs to be changed.
{{TODO|Define a compliance checking tool (e.g. [http://pear.php.net/package/PHP_CodeSniffer PHP Code Sniffer] used by PEAR) and automate the process}}
{{TODO|Codify all rules into automation process, starting with [https://github.com/StartupAPI/users/blob/master/.phptidy-config.php .phptidy-config] file}}
== Indentation == All PHP code in the application must use tabs for indentation.
Following comment can be included at the top of every PHP page, right after first opening PHP tag:
This will allow vi users to automatically enforce indentation of the code.
For formatting the page automatically using VI, use 1GVG= command sequence.
== Comments == Complete inline documentation comment blocks (docblocks) must be provided. Further information can be found on the [http://phpdoc.org/ phpDocumentor website].
Non-documentation comments are strongly encouraged. A general rule of thumb is that if you look at a section of code and think "Wow, I don't want to try and describe that", you need to comment it before you forget how it works.
C style comments (/* */) and standard C++ comments (//) are both fine. Use of Perl/shell style comments (#) is discouraged.
== Control structures == Same as for [http://pear.php.net/manual/en/standards.control.php PEAR project]
=== Always use curly braces === Even if control block contains only one statement, always use curly braces around that statement.
{{TODO|Include argumented explanation for the benefits of this}}
=== No alternative styles === [http://us1.php.net/manual/en/control-structures.alternative-syntax.php Alternative style] for PHP control structures should never be used.
== Use only classic PHP open tag == PHP has an [http://us2.php.net/manual/en/ini.core.php#ini.short-open-tag option to enable a short open tag]: '''<?''' and it's companion short echo tag '''<?='''
While very convenient, it's not on by default and '''will likely be disabled on the servers people use'''.
Please us '''<?php''' and regular echo command '''<?php echo''' instead of short open tag and configure your development environment not to accept short tags to avoid this bug sneaking in (it's very painful to remove them).
== DIR ==
When you need to refer to another file within the project (e.g. to include it or read from disk), please use PHP [http://us2.php.net/manual/en/function.dirname.php dirname()] function with [http://us2.php.net/manual/en/language.constants.predefined.php magic constant] DIR to calculate the resulting path of the file.
For example to include file2.php located in the same folder:
=== Going up the folder chain ===
In order to go up the folder chain, please do not use double dots (/../) to indicate parent folder, but use nested dirname() instead.
For example to include file3.php located one folder above current file:
==Objects, IDs and slugs == It is important to distinguish objects from object IDs and object IDs from object wikipedia:Slug (web publishing) in the code, in the database and in configuration files.
It is preferred to pass objects when passing from one class to another, but (ideally private) functions within the same class can pass object IDs or object slugs.
Object IDs MUST always be integers while object slugs MUST always be strings.
To allow for better code readability and to avoid confusion between objects, their IDs and their slugs, variables in the code and field names in database should use the following naming convention: Object IDs must always have "_id" suffix, e.g. plan_id Object slugs must always have "_slug" suffix, e.g. plan_slug
When stored in the database, objects should be identified by ID or by slugs.
If object IDs are defined in the code, named constants must be used to help readability, for example:
=== Slugs === wikipedia:Slug (web publishing) should be URL-friendly, meaning that they should be the same as their URL-encoded version without resorting to %-encoding.
Slugs should not use wikipedia:CamelCase, but lower case latin letters and utilize dashes (-) (not underscores) in place of spaces.
== Do not convert strings into variables == Do not convert strings into variables and vice versa, all variable assignments should be done through accessing methods that can have documentation with type definitions to allow autocompletion, static code analysis and etc.
This is very important for future debugging, tracing for source of errors and so on.
It's better to have more code and be explicit about your intentions then having smaller code that is harder to read and understand.
It's better to spend time adding more lines of code with type annotations and documentation when you need to add extra field then to spend more time trying to debug the issue and refactor the code to be self descriptive.
=== NO __get() & __set() === Instead of using __get and __set magic functions, use accessor (getter and setter) methods.
Best practice for read-only properties:
/**
* @return string Name of the widget
*/
function getName() {
return $this->name;
}
}
to allow for IDE autocompletion, automated configuration and so on.
=== NO extract() & compact() === extract() allows to convert arrays into variables which makes it impossible to track the origin of some variables, their scope and sometimes even dangerous when you don't control the source of data. Same applies to compact() as result is usually used by extract().
For converting arrays of data into variables, instead of using a shortcut:
extract($my_data); // ambiguous, hides declaration of variables
echo $name . ' is ' . $age . ' years old ' . $gender;
Best practice :
// verbose, but specific $name = $my_data['name']; $age = $my_data['age']; $gender = $my_data['gender'];
echo $name . ' is ' . $age . ' years old ' . $gender;