PHP coding style guide
The PHP coding style guide at Outlast is based on the existing coding style implemented within the Outlast Framework. All developers must follow this when developing in PHP at Outlast. Some of the text below is used from CodeIgniter’s style guide but updated as needed.
File formats, encoding, line endings
All files must use the .php
extension.
Files should be saved with Unicode UTF-8
encoding. The BOM should not be used. Unlike UTF-16 and UTF-32, there’s no byte order to indicate in a UTF-8 encoded file, and the BOM can have a negative side effect in PHP of sending output, preventing the application from being able to set its own headers.
Unix line endings should be used (LF). Be careful, Windows users usually need to set this up in their editor manually!
PHP tags
The full PHP opening tag <?php
should be used in all files.
Closing tags should not be used at the end of PHP files because they can cause errors if accidental spaces are added after the closing tag. This includes most PHP files in OFW – typically they are only PHP with no HTML output mixed in, so there will be no closing tag.
Here is a proper example:
INCORRECT: <?php echo "Here's my code!"; ?> CORRECT: <?php echo "Here's my code!"; /* End of file myfile.php, no closing tag. */
Class and method naming
Classes should be CamelCase with no underscores. Model classes should be defined as singular nouns, such as User
instead of Users
.
INCORRECT: class My_class class myclass CORRECT: class MyClass
Method names should be_lowercase_and_use_underscores
. They should also always include public
or private
.
INCORRECT: function fileproperties() // not descriptive and needs underscore separator and private/public public function fileProperties() // not descriptive and uses CamelCase public function getfileproperties() // Better! But still missing underscore separator private function getFileProperties() // wrong, uses CamelCase public function get_the_file_properties_from_the_file() // too wordy CORRECT: public function get_file_properties() // descriptive, underscore separator, and all lowercase letters
Static and magic methods
Static methods are used in OFW to create and fetch objects. They should be styled exactly as any other method with underscores and lowercase:
CORRECT: public static function fetch_by_user()
Magic methods are used in OFW as triggers when certain actions occur. A common example is __afterFetch()
in models where caching of certain data can occur. It is important that unlike other methods, magic methods use __lowerCamelCase()
and are always preceded by two underscores.
INCORRECT: public function __AfterFetch() // Wrong! Capitalized first letter. public function __after_fetch() // Wrong! Not CamelCase. public function afterFetch() // Wrong! No underscore preceding. public function _afterFetch() // Wrong! Only a single underscore preceding. CORRECT: public function __beforeSave() // Correct!
Variable and method properties
The guidelines for variable naming is very similar to that used for class methods. Namely, variables should contain only lowercase letters, use underscore separators, and be reasonably named to indicate their purpose and contents. Very short, non-word variables should only be used as iterators in for() loops.
INCORRECT: $j = 'foo'; // single letter variables should only be used in for() loops $Str // contains uppercase letters $bufferedText // uses CamelCasing, and could be shortened without losing semantic meaning $groupid // multiple words, needs underscore separator $name_of_last_city_used // too long CORRECT: for ($j = 0; $j < 10; $j++) $str $buffer $group_id $last_city
Method properties should use the same logic and should always be declared!
class RandomExample{ public $example_property = true; public function random_method(){ // Below is WRONG! It is a non-declared property. $this->some_other_property = false; // Below is CORRECT! It is using the declared property from above. $this->example_property = false; } }
Constants
Constants follow the same guidelines as do variables, except constants should always be fully uppercase and need to be declared at the top of each PHP file.
declare('EXAMPLE_CONSTANT', 25); // CORRECT!
Comments and documentation
In-code documentation and lengthy commenting is an essential part of coding style at Outlast. You MUST use comments and you MUST use it more often than you think you should. 🙂
Here’s a correct example:
function add_numbers($number1, $number2 = false){ // Number2 defaults to the same value as number1 if it is false if($number2 === false) $number2 = $number1; // Now add and return return $number1 + $number2; }
You don’t have to comment on every line, but you do have to comment each code block (every few lines). Even obvious code segments should be commented. Why? Because it makes code review and code debug much easier by others (and by yourself if you come back to the code in a few months).
Another important facet is to always use DOCBLOCK comments for each class, method, and variable. This helps software such as PHPStorm
autocomplete and suggest code properly. It also helps us standardize and generate documentation.
Here’s a correct example of using DOCBLOCK:
/** * Returns an error message and exists. Useful for fatal errors. * @param string $message The error message to display and/or log. * @return bool Does not return anything. * @link http://www.externallink.com/only/if/needed/ **/ public function error($message){ // Manually load error reporting lib /* @var zajlib_error $error */ $error = $this->load->library('error'); // Now report the error and send 500 error if(!$this->output_started) header('HTTP/1.1 500 Internal Server Error'); $error->error($message); exit; }
Notice that each @param
is documented as is the @return
value. Also, notice how @var
is used within the code to tell the compiler what return value it should expect from the method. Unlike the method DOCBLOCK, this is not required but it is quite helpful for autocomplete and code validation.
Finally, notice how every few lines are commented (and the code is indented – more about that later). Such commenting is required, even if the code segment logic is obvious to you as you are writing it.
Helpful tip For reusable models (such as those used in plugins or the OFW system) you should create a separate doc.php
file to document the various fields available in that model. See OFW’s /system/doc/doc.php
as an example.
Helpful tip For a full list of DOCBLOCK tags, see the documentation.
Booleans and null
Always use the lower case version.
INCORRECT: $variable = TRUE; CORRECT: $variable = false;
Logical Operators
Always use the symbol version.
INCORRECT: if($var1 == 1 AND $var2 == 2) echo "woo!"; CORRECT: if($var1 == 1 && $var2 == 2) echo "woo!";
Always use the strict type comparison (===, !==, etc.) where possible.
INCORRECT: if(strpos($str, 'foo') == false) CORRECT: if(strpos($str, 'foo') === false)
Error handling
Do not use exceptions within the context of Outlast Framework. Instead use the notice()
, warning()
, and error()
and return its values.
Here’s an example:
function do_something(){ // .... // If I failed if($failed) return $this->zajlib->warning("Failed to do something"); }
Warnings will continue execution, errors are fatal and halt execution. Warning and errors are only displayed in debug mode. If you want to display the error in live mode as well (which is usually not recommended) then you can use set the second parameter to true:
return $this->zajlib->error("Fatally failed to do something", true);
Brackets and code blocks
Short code blocks can be placed on a single line:
if($is_true) echo "It's true!";
Longer lines or multi-line code blocks require brackets and else blocks are on separate lines:
if($is_true){ echo "Indeed, I must say that this is rather true"; } else{ echo "Nope, it is not true."; }
There is no space before opening brackets.
Indentation and whitespace
Do not place any whitespace before the opening php tag and just skip using the closing tag (see above). Whitespace before the <?php
tag will cause errors!
For indentation, set your IDE to use tabs instead of spaces. If you must use spaces, you should set it to 4 spaces.
Although not always the case in OFW core code currently, indentation should generally follow the Stroustrup variant of K&R style but with some modifications.
Here are some proper examples:
public function redirect($url, $frame_breakout = false){ // Opening bracket on same line, no preceding space // Comments are on the first level of indentation, code is indented further if(!$this->url->valid($url)) $url = $this->baseurl.$url; // If statements can be on the same line if simple, single line logic // If test is running, return url if($this->test->is_running()) return $url; // Frame breakout or standard? if($frame_breakout){ // You can also have multi-line if statements, with brackets. Again, bracket on same line, no space. exit("<script>window.top.location='".addslashes($url)."';</script>"); } else{ // Else is not nested, bracket is the same as before. header("Location: ".$url); } exit; }
Spacing is also quite limited:
INCORRECT: foreach( $query->result() as $row ) CORRECT: foreach($query->result() as $row) // No space after foreach, no space after or before parenthesis
SQL Queries
MySQL keywords are always capitalized: SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN, etc.
IMPORTANT! Always use the dbo
library and properly escape all variables.
Break up long queries into multiple lines for legibility, preferably breaking for each clause.
Strings and concatenation
Always use single quoted strings unless you need variables parsed, and in cases where you do need variables parsed, use braces to prevent greedy token parsing. You may also use double-quoted strings if the string contains single quotes, so you do not have to use escape characters.
INCORRECT: "My String" // no variable parsing, so no use for double quotes "My string $foo->var" // needs braces 'SELECT foo FROM bar WHERE baz = \'bag\'' // ugly CORRECT: 'My String' "My String $var" // correct with or without braces "My String {$var}" "My string {$foo->var}" "SELECT foo FROM bar WHERE baz = 'bag'"
When concatenating, do not use spaces between dots:
INCORRECT: $string = 'Lorem ipsum, ' . $var . ' More...'; CORRECT: $string = 'Lorem ipsum, '.$var.' More...';
Version control
All code must use version control (Git). Never leave old code segments in /** comments **/ – instead commit often and rely on Git to have quick access to all previous versions of your code.
For more on version control see the Outlast Git and deployment workflow.
Autoformatting
Autoformatting is not recommended because it can change lots of rows all at once (which causes confusion during code review) and can sometimes mess things up. Instead, programmers should manually follow all rules in this document.