Oh no! Where's the JavaScript?
Your Web browser does not have JavaScript enabled or does not support JavaScript. Please enable JavaScript on your Web browser to properly view this Web site, or upgrade to a Web browser that does support JavaScript.

PHPFusion Coding Standards

Docs
Contributors
Falk edited PHPFusion Coding Standards on 25/10/2020
Falk added XSS Filtering on 26/05/2015
Falk added CSRF protection on 26/05/2015
Falk added Validation of input data on 28/05/2015
Falk added Safety first on 15/06/2015
Falk added Code in English on 15/06/2015
Falk added Index Files on 28/05/2015
Falk added File Format on
Falk edited File Format on 05/11/2020
Falk added Line Breaks on 27/05/2015
Falk added Limit Line Length on 27/05/2015
Falk added Whitespace in Files on 27/05/2015
Falk added Short Open Tags on 27/05/2015
Falk added PHP Closing Tag on 27/05/2015
Falk added File Naming on 27/05/2015
Falk added Headers on 27/05/2015
Falk added Modifying headers on 29/05/2015
Falk added Secure Includes on 28/05/2015
Falk added Always use echo on 27/05/2015
Falk added HTML as Lowercased on 27/05/2015
Falk added Control Structures on 27/05/2015
Falk added Indentation on 15/06/2015
Falk added Whitespace for indentation on 27/05/2015
Falk added One File per Class on 27/05/2015
Falk added Class and Function Naming on 13/01/2016
Falk added Commenting on 27/05/2015
Falk added Code Grouping on 27/05/2015
Falk added Avoid Deep Nesting on 27/05/2015
Falk added Logical Operators on 27/05/2015
Falk added Ternary Operator on 29/05/2015
Falk added Semicolons on 27/05/2015
Falk added Quotes on 27/05/2015
Falk added String Concatenations on 29/05/2015
Falk added Variables on 27/05/2015
Falk added Constants on 27/05/2015
Falk added Aligning Arrays on 28/05/2015
Falk added Debugging Code on 27/05/2015
Falk edited Database encodings on 26/10/2020
Falk added SQL Queries on 27/05/2015

PHPFusion Coding Standards

XSS Filtering

Cross Site Scripting filter.
This filter looks for commonly used techniques to embed malicious JavaScript into your data, or other types of code that attempt to hijack cookies or do other malicious things.

CSRF protection

CSRF stands for Cross-Site Request Forgery, which is the process of an attacker tricking their victim into unknowingly submitting a request.
PHPFusion provides a CSRF protection out of the box, which will automatically trigger when you submit forms via PHPFusion Dynamics.

Validation of input data

PHPFusion Defender have form validation that assists you in validating, filtering, and prepping your data.
Even if that doesn’t work for your use, be sure to always validate and sanitize all input data.
If you expect a numeric string for an input variable, you can check for that with the isnum() function.
If you pass data with form posts or $_GET, you should always use the form_sanitizer() or stripinput() function to sanitize the posted data.
Please keep in mind that this includes not only $_POST and $_GET variables but also cookies, strings and basically all data that is not created directly by your own code.

Safety first

Always validate data to ensure that it contains the correct chars, types, length, size, etc.
Always filter the data as if it were tainted.
PHPFusion provides quite a few functions and tips to assist you in this process.

Code in English

All comments, variable names, function names, class names, strings etc should always be in English.

Index Files

Always have an empty index.php file in your directories when you do not use index.php as the standard opening file.
You must have an empty index.php in your images, js, css, templates, etc. folders as well.

File Format

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. 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).

You can read more about UTF-8 in UTF-8 Explained

Line Breaks

Files must be saved with Unix line breaks.
Ensure that your text editor is configured to save files with Unix line breaks

Limit Line Length

Our eyes are more comfortable when reading tall and narrow columns of text.
We consider it to be good practice to avoid writing horizontally long lines of code.
In general, all lines of code should not be longer than 80 chars.

Whitespace in Files

No whitespace can precede the opening PHP tag or follow the closing PHP tag.
Output can be buffered, so whitespace in your files can cause output to begin before PHPFusion outputs its content, leading to errors and an inability to send proper headers.

Short Open Tags

Always use full PHP opening tags, not all servers have short_open_tag enabled.

INCORRECT
Code
<? echo $foo; ?>

Code
<?=$foo?>


CORRECT
Code
<?php 
echo $foo;
?>

PHP Closing Tag

The PHP closing tag on a PHP document ?> is optional to the PHP parser.
However, if used, any whitespace following the closing tag, whether introduced by the developer, user, or an FTP application, can cause unwanted output followed by PHP errors, or if the latter are suppressed, blank pages.
For this reason we want all PHP files to omit the PHP closing tag and end with a single empty line instead.

File Naming

Class filenames should always start with an uppercase letter, while any other file name (configurations, views, generic scripts, etc.) should all be in lowercase.
Class file names should match the name of the class itself. For example, if you have a class named Myclass, then its filename should also be Myclass.php.
Multiple words should be separated with an underscore.

INCORRECT
someclass.php
someClass.php
SOMECLASS.php
Some_Class.php

CORRECT
Someclass.php
Some_class.php

Headers

Headers provides a description of the file and it should usually include Copyright, Filename, Author, License.
Example of a standard header,
Code
/*-------------------------------------------------------+
| PHPFusion Content Management System
| Copyright (C) PHPFusion Inc
| https://www.php-fusion.co.uk/
+--------------------------------------------------------+
| Filename: Filename.php
| Author: PHPFusion Development Team
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/

Modifying headers

When you write a Custom New File, then you are the Author of the file:

Quote

+--------------------------------------------------------+
| Filename: Filename.php
| Author: Your Name (Username/Nickname)
+--------------------------------------------------------+

When you have modified someone’s file quite a bit beyond a few fixes, you would qualify as a Co-Author and you can increment the header as follows,

Quote

+--------------------------------------------------------+
| Filename: Filename.php
| Author: PHPFusion Development Team
| Co-Author: Your Name (Username/Nickname)
+--------------------------------------------------------+


Your are not allowed to alter the PHPFusion Copyright´s or the License section unless you are a PFDN member that use EPAL

Secure Includes

When you create files that are intended to work as an include to the Core, always add a check to prevent direct access to these includes.
This also applies to panels, functions, classes and similar.
Files such as Locales, CCS, JS files etc can be excluded from this Standard.

Snippet to use,
Code
if (!defined("IN_FUSION")) { die("Access Denied"); }


The code should be one line directly after the header, as displayed below.
Code
/*-------------------------------------------------------+
| PHPFusion Content Management System
| Copyright (C) PHPFusion Inc
| https://www.php-fusion.co.uk/
+--------------------------------------------------------+
| Filename: Filename.php
| Author: PHPFusion Development Team
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/
if (!defined("IN_FUSION")) { die("Access Denied"); }

Always use echo

Always make use of echo to print a text in the output.

INCORRECT
Code
print "This is some text.";


CORRECT
Code
echo "This is some text.";

HTML as Lowercased

Your HTML must always be containing Lowercase characters.
Uppercase characters are not XHTML compatible.

INCORRECT
Code
echo "<STRONG>I Love PHPFusion.</STRONG>n";


CORRECT
Code
echo "<strong>I Love PHPFusion.</strong>n";

Control Structures

PHPFusion should not use Alternative syntaxes for Control Structures.
Always avoid to jump in and out of in PHP.
Do not use PHP short tags.
Content should be echoed.
Statements should be opened and closed with curly braces.

INCORRECT
// Does not use curly braces and keeps jumping in and out of PHP while PHP short tag is occasionally used.
Code
<? if ($username == 'User 1'): ?>
   <h3>Hi User 1</h3>
<?php elseif ($username == 'User 2'): ?>
   <h3>Hi User 2</h3>
<? else: ?>
   <h3>No matching users found</h3>
<?php endif; ?>


CORRECT
// Using curly braces and does not jump in and out of PHP, echos the content and not using PHP short tags.
Code
<?php 
if ($username == 'User 1') {
   echo "<h3>Hi User 1</h3>";
} elseif ($username == 'User 2') {
   echo "<h3>Hi User 2</h3>";
} else {
   echo "<h3>No matching users found</h3>";
}
?>

Indentation

PHPFusion use a indent style called Kernel style - 1TBS, Also known as the one true brace style.
Make sure that your editor does not automatically indent all codes with one tab level from start.

INCORRECT
// Everything is tabbed out one level, curly brace is on a new line, overall , inconsistent tabbing and spacing.
Code
   function foo($bar) 
   {
   if (x <0) {
    return $negative;
    } elseif (x>0) {
            return $positive;
    } else {
   return $unknown;
    }
   }


CORRECT
Code
function foo($bar) {
   if (x < 0) {
      return $negative;
   } elseif (x > 0) {
      return $positive;
   } else {
      return $unknown;
   }
}

Whitespace for indentation

Never use whitespace for indentation in your code, always use tabs with the exception of aligning arrays.
It results in more compact files, storing one tab character versus, say, four space characters.

Bracket and Parenthesis Spacing

Parenthesis and Brackets should not use any additional spaces.
The exception is that a space should always follow PHP control structures that accept arguments with parenthesis such as
(declare, do-while, elseif, for, foreach, if, switch, while), to help distinguish these from functions and in order to increase code readability.

INCORRECT
// Spaces around array keys
Code
$arr[ $foo ] = 'foo';


CORRECT
// No spaces around array keys
Code
$arr[$foo] = 'foo'; 


INCORRECT
// Spaces around parenthesis in function declarations
Code
function foo ( $bar ) {
}


CORRECT
// No spaces around parenthesis in function declarations
Code
function foo($bar) {
}


INCORRECT
// A single space in interior parenthesis
Code
foreach( $result->result() as $data )


CORRECT
// A single space following PHP control structures, but not in interior parenthesis
Code
foreach ($result->result() as $data) 

One File per Class

Use separate files for each class, unless the classes are closely related.

Class and Function Naming

Class functions should named to clearly indicate their function, preferably including a verb.
Try to avoid overly long and verbose names and separate multiple words with underscores.

INCORRECT
Code
class megaclass
class MegaClass


CORRECT
Code
class Mega_class {
public function __construct() {
 }
}


INCORRECT
// Not descriptive and needs underscore separator
Code
function fileproperties() {
}

// Better, still missing underscore separator
Code
function getfileproperties() {
}

// Way to much words
Code
function get_the_file_properties_from_the_file() {
}


CORRECT
// Descriptive with clear underscore separators
Code
function get_file_properties() {
}

Commenting

Comments help to describe the flow and intent of the code.
When the code is quite obvious, it is not productive to repeat it with a lot of comments.
If you comment on the code, you can simply combine it to a single line in most of the cases.

INCORRECT
Code
// Prevent any possible XSS attacks via $_GET.
// Check if we have a stripget($_GET) function request
if (stripget($_GET)) {
   // The request found a bad pattern, terminate the script
   die("Prevented a XSS attack through a GET variable!");
}
// End of function


CORRECT
Code
// Prevent any possible XSS attacks via $_GET.
if (stripget($_GET)) {
   die("Prevented a XSS attack through a GET variable!");
}


DocBlock style commenting is something we should use preceding class, method, and property declarations so they can be picked up by IDEs

CORRECT
Code
/**
* Class name
*
* @package      Package Name
* @subpackage   Subpackage
* @category      Category
* @author      Author Name
* @link         http://example.com
*/


CORRECT
Code
class Class name {
/**
* Encodes string for use in example
*
* @param string $example Input string
* @return string
*/
function encode_example($example)
/**
* Data for class manipulation
*
* @var array
*/

Code Grouping

Most often, certain tasks require quite a few lines of code.
It is a good idea to keep these tasks grouped within separate blocks of code.
This is best achived by adding a break.
By adding a comment at the beginning the blocks, you also emphasizes the visual separation.

INCORRECT
Code
if (stripget($_GET)) {
   die("Prevented a XSS attack through a GET variable!");
}
dbconnect($db_host, $db_user, $db_pass, $db_name);
unset($db_host, $db_user, $db_pass);


CORRECT
Code
// Prevent any possible XSS attacks via $_GET.
if (stripget($_GET)) {
   die("Prevented a XSS attack through a GET variable!");
}

// Establish mySQL database connection
dbconnect($db_host, $db_user, $db_pass, $db_name);
unset($db_host, $db_user, $db_pass);

Avoid Deep Nesting

With many nested levels the code is harder to read and follow, even with proper Indentation.

INCORRECT
Code
function do_stuff() {
// Things to do
   if (is_writable($folder)) {
      if ($fp = fopen($file_path,'w')) {
         if ($stuff = get_some_stuff()) {
            if (fwrite($fp,$stuff)) {
               // Things to do
            } else {
               return false;
            }
         } else {
            return false;
         }
      } else {
         return false;
      }
   } else {
      return false;
   }
}


CORRECT
Code
function do_stuff() {

// Things to do

   if (!is_writable($folder)) {
      return false;
   }

   if (!$fp = fopen($file_path,'w')) {
      return false;
   }
 
   if (!$stuff = get_some_stuff()) {
      return false;
   }

   if (fwrite($fp,$stuff)) {
   // Things to do
   } else {
      return false;
   }
}

Logical Operators

Use of the || “or” comparison operator is discouraged, as its clarity on some output devices is low (looking like the number 11, for instance).
&& is preferred over AND but either are acceptable, and a space should always precede and follow !.

INCORRECT
Code
if ($foo || $bar)

// Okay but not recommended for common syntax highlighting applications
Code
if ($foo AND $bar) 

Code
if ($foo == FALSE)


CORRECT
Code
if ($foo OR $bar)

// Best practise
Code
if ($foo && $bar) 

Code
if (!$foo)

Code
if (!is_array($foo))


Comparing Return Values and Typecasting
Some PHP functions return FALSE on failure, but may also have a valid return value of “” or 0, which would evaluate to FALSE in loose comparisons.
Be explicit by comparing the variable type when using these return values in conditionals to ensure the return value is indeed what you expect, and not a value that has an equivalent loose-type evaluation.

Use the same stringency in returning and checking your own variables. Use === and !== as necessary.

Ternary Operator

Ternary operators are encouraged, always have them test if the statement is true and not false, Otherwise, it just gets confusing.

// (if statement is TRUE) ? (Do this) : (else, do this);
Code
$standard = ($is_true == TRUE) ? "Yes" : "No";

Semicolons

The PHP language requires semicolons at the end of most lines, but allows them to be omitted at the end of code blocks.
PHPFusion Coding Standards requires them, even at the end of code blocks.

INCORRECT
Code
echo $variable 


CORRECT
Code
echo $variable;

Quotes

PHPFusion is most often using double quotes when echoing it´s content and when handling Constants, Variables etc.

INCORRECT
// Double quotes are required to avoid escaping
Code
'SELECT foo FROM bar WHERE baz = 'bag''

// Does not use double quotes when echoing content
Code
echo 'My $varible';


CORRECT
// No Quotes are required
Code
"SELECT foo FROM bar WHERE baz = 'bag'"

// Using double quotes when echoing content and variable
Code
echo $varible." with some text";

// Using double quotes when echoing content
Code
echo "My content";

// Using double quotes when calling Constants.
Code
include INFUSIONS."my_panel//my_panel_include.php";

String Concatenations

PHPFusion is most often using double quotes when echoing it´s content and when handling Constants, Variables etc.
Always use a space between the dot and the concatenated parts to improve readability.

INCORRECT
// No double quotes, bas spacing.
Code
$string = "Foo" . $bar;
$string=$bar.'foo';
$string= bar() 'foo';
$string= 'foo'. 'bar';


// Concatenating assignment operator lacks spaces on the sides
Code
$string.="Foo";
$string.=$bar;
$string.=baz();



CORRECT
// When you concatenate simple variables, you can use double quotes and add the variable inside.
Code
$string = "Foo" . $bar;
$string = $bar . "foo";
$string = bar() . "foo";
$string = "foo" . "bar";


// When using the concatenating assignment operator (.=) use a space on each side.
Code
$string .= "Foo";
$string .= $bar;
$string .= baz();

Variables

The guidelines for variable naming are very similar to those used for classes and functions.
Variables should contain only lowercase letters, use underscore separators.
The naming should be made in such manner that it is and indicator of their purpose and contents.
Very short, non-wordy variables should only be used as iterators in for() loops.

INCORRECT
// Single letter variables should only be used in for() loops
Code
$k = "foo"; 

// Contains uppercase letters
Code
$Str 

// Uses CamelCasing, and could be shortened without losing semantic meaning
Code
$bufferedText 

// Uses multiple words, needs underscore separator
Code
$groupid 

// Way too long
Code
$name_of_last_city_used 


CORRECT
// Correct for() looping with use of single letter variable
Code
for ($k = 0; $k < 10; $k++)

// Lowercase letters
Code
$str

// We get the idea with no CamelCase
Code
$buffer

// Multiple words with underscore as separator
Code
$group_id

// Quite clear what it does in a short version
Code
$last_city

Constants

Constants follow the same guidelines as variables, except constants should always be fully uppercase.
Always use Core constants when appropriate, i.e. INFUSIONS, NEWS, BASEDIR, IMAGES, etc.
The naming should be made in such manner that it is and indicator of the purpose and contents.
Very short, non-wordy constants should not be used.


INCORRECT
// Missing underscore separator and not fully uppercase
Code
newbasedir

// Do not use single letter constants
Code
N 

// Not descriptive at all
Code
S_C_VER


CORRECT
Code
NEW_BASEDIR

Code
GOOD


TRUE, FALSE, and NULL keywords should always be fully uppercase.

INCORRECT
Code
if ($foo == true)
$bar = false;
function foo($bar = null)

CORRECT
Code
if ($foo == TRUE)
$bar = FALSE;
function foo($bar = NULL)

Aligning Arrays

Arrays should be formatted with a space separating each element after the comma (,) and spaces around the => key association operator if possible.
Note that if the line declaring an array spans longer than 80 characters, each element should be broken into its own line and indented one level

INCORRECT
// No spacing
Code
$my_array = array("apple"=>"red","banana"=>"yellow","watermelon"=>"green");


// Bad indentation and mixed breaks, inconsistent spacing.
Code
$my_array = array(
 "apple"=> "red", "banana"=>"yellow",
 "watermelon" =>"green",
"Lemon"=> "yellow",
"Strawberry" => "red");

CORRECT
// Spacing as required
Code
$my_array = array("apple" => "red", "banana" => "yellow", "watermelon" => "green");


// Good indentation, nice breaks, consistent spacing, ends with a ,
Code
$my_array = array(
   "apple" => "red",
   "banana" => "yellow",
   "watermelon" => "green",
   "Lemon" => "yellow",
   "Strawberry" => "red",
);


The comma at the end of the last array allows the parenthesis to have it´s own line,
it also allows help to prevent parsing errors if another element is placed at the end of the list later.

Debugging Code

Do not leave debugging code in your submissions, even when commented out.
Things such as var_dump(), print_r(), die(), exit() should not be included in your code unless it serves a specific purpose other than debugging.

Database encodings

PHPFusion are using utf8mb4_unicode_ci for it´s Database encodings as default from PHPFusion 9.0.

You can read more about it in UTF-8 Databases

SQL Queries

SQL keywords should always be capitalized, SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN, etc.

Break up extra long queries into multiple lines for readability, make the break for each clause.

INCORRECT
// Keywords are lowercase and query is on one line
Code
$result = dbquery("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");

// One very huge line
Code
$result = dbquery("SELECT f.*, f2.forum_name AS forum_cat_name, t.thread_id, t.thread_lastpost, t.thread_lastpostid, t.thread_subject, u.user_id, u.user_name, u.user_status, u.user_avatar FROM ".DB_FORUMS." fLEFT JOIN ".DB_FORUMS." f2 ON f.forum_cat = f2.forum_id LEFT JOIN ".DB_FORUM_THREADS." t ON f.forum_lastpostid = t.thread_lastpostid LEFT JOIN ".DB_USERS." u ON f.forum_lastuser = u.user_id ".(multilang_table("FO") ? "WHERE f.forum_language='".LANGUAGE."' AND" : "WHERE")." ".groupaccess('f.forum_access')." AND f.forum_id='".intval($this->forum_info['forum_id'])."' OR f.forum_cat='".intval($this->forum_info['forum_id'])."' OR f.forum_branch='".intval($this->forum_info['forum_branch'])."' ORDER BY forum_cat ASC"); 

CORRECT
// Keywords are capitalized and the query is easily readable.
Code
$result = dbquery("SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz FROM exp_pre_email_addresses WHERE foo != 'oof' AND baz != 'zab' ORDER BY foobaz LIMIT 5, 100");


// Query have a new line at each new clause.
Code
$result = dbquery("SELECT f.*, f2.forum_name AS forum_cat_name,
t.thread_id, t.thread_lastpost, t.thread_lastpostid, t.thread_subject,
u.user_id, u.user_name, u.user_status, u.user_avatar
FROM ".DB_FORUMS." f
LEFT JOIN ".DB_FORUMS." f2 ON f.forum_cat = f2.forum_id
LEFT JOIN ".DB_FORUM_THREADS." t ON f.forum_lastpostid = t.thread_lastpostid
LEFT JOIN ".DB_USERS." u ON f.forum_lastuser = u.user_id
".(multilang_table("FO") ? "WHERE f.forum_language='".LANGUAGE."' AND" : "WHERE")." ".groupaccess('f.forum_access')."
AND f.forum_id='".intval($this->forum_info['forum_id'])."'
OR f.forum_cat='".intval($this->forum_info['forum_id'])."'
OR f.forum_branch='".intval($this->forum_info['forum_branch'])."'
ORDER BY forum_cat ASC");