The purpose of this document is to establish a standard for all PHP and HTML code written for Ampache. This document will outline stylistic standards for code such as indentation and spacing. It will also detail naming conventions for functions and files as well as the logical layout of files under the web space. It will also outline some basic coding practices, or standards that all new Ampache PHP code should meet.
Use an indent of a four spaces. It is recommended that you break lines at approximately 75-85 characters. There is no standard rule for the best way to break a line, please use your best judgment. The goal is to make the PHP files easy to read by a third party.
These include if, for, while, switch, etc. Here is an example if statement, since it can be the most complicated:
<?php
if ((condition1) || (condition2)) {
action1;
}
elseif ((condition3) && (condition4)) {
action2;
}
else {
defaultaction;
}
if ((condition1)) {
while ($foo) {
do_stuff();
}
} // end if
?>
Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls. Always use curly braces even in situations where they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.
For switch statements:
<?php
// Simple Case
switch (condition) {
case 1: action1; break;
case 2: action2; break;
default: defaultaction; break;
}
// Complex Case
switch (condition) {
case 1:
action1;
action2;
break;
case 2:
case 3:
action1;
action2;
break;
default:
action1;
break;
} // end switch condition
?>
Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; spaces between commas and each parameter; and no space between the last parameter, the closing parenthesis, and the semicolon.
Example:
<?php $var = foo($bar, $baz, $quux); ?>
As displayed above, there should be one space on either side of an equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, assignments can be aligned to promote readability:
<?php $short = foo($bar); $long_variable = foo($baz); ?>
Binary and ternary operators should be fully spaced out. Unary operators will generally not be.
<?php $foo = $bar . 'baz'; $foo = $bar ? $baz : $quux; $foo = !$baz; $foo++;
echo, require, and require_once are not functions and do not require parentheses around their arguments. To distinguish them from real function calls, do not use the optional parentheses when calling them.
<?php require_once 'lib/init.php'; echo 'Initialised.'; ?>
Classes should be given descriptive names. Avoid using abbreviations where possible. Class names should always begin with an uppercase letter. The class hierarchy is also reflected in the class name. Classes should be named using Camel_Caps. Examples of good class names are:
Log Net_Finger HTML_Upload_Error
Functions and methods should be named with all lower case using underscores between words or levels of hierarchy
Example:
connect(); get_data(); build_some_widget(); xmlrpc_serialize_data(); xmlrpc_unserialize_data();
Private class members (meaning class members that are intended to be used only from within the same class in which they are declared; PHP does not yet support truly-enforceable private name spaces) should be preceded by a single underscore. For example:
_sort(); _init_tree(); $this->_status;
Constants should always be all-uppercase, with underscores to separate words. The true, false and null constants are excepted from the all-uppercase rule, and must always be lowercase.
In the interest of future readability, code should always use full named variables unless a commonly known acronym can be used in its place. For example
// An Upload Directory $upload_directory = '/tmp'; // XMLRPC result $xmlrpc_result = $xmlrpc->get_results();
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 to describe that”, you need to comment it before you forget how it works. C style comments (/* */) are fine, but standard C++ comments (//) are preferred.
Use require_once whenever possible, otherwise use require. Only libraries, classes, modules and templates should be included. All includes should whenever possible be placed at the top of the file before any functions, or operations are performed.
Example of Incorrect Including:
index.php <<
<?php
if ($_REQUEST['action'] == foo) {
do_stuff();
}
include_once 'default_action.php';
?>
>>
default_action.php <<
<?php
/* This is the default action performed when visiting index.php */
if ($_REQUEST['action'] != foo OR !isset($_REQUEST['action'])) {
do_default_stuff();
}
?>
>>
Example of Correct Including:
index.php <<
<?php
include_once conf('prefix') . '/default_action.php';
if ($_REQUEST['action'] == foo) {
do_stuff();
}
else {
default_action();
}
?>
>>
default_action.php <<
<?php
function default_action() {
do_default_stuff();
}
?>
>>
Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. There are no exceptions to this rule.
Follow the below naming conventions when creating new functions to make your code easy to read. When creating functions use the following prefixes:
Examples:
/* Echoes information, doesn't return */ print_foo() /* Returns information */ get_foo() /* Gets information then includes an html template */ show_foo() /* Create new Object */ create_foo() /* Delete Object */ delete_foo()
All scripts written must:
There should be no line feeds after the closing PHP tag (?>) to prevent output before headers are sent.
In order to maintain some semblance of organization on the web servers all files should be organized based on their function. <ROOT> refers to the top of the file path for the web server. All libraries should be located in <ROOT>/lib. Any additional modules that are suitable for separate distribution or not written in shop should be put in <ROOT>/modules/<name of module>. All HTML templates should be put in <ROOT>/templates. All images for the site should be under <ROOT>/images. If a single subsection is going to contain a large number of images although not require it would most likely be a good idea to create a sub-directory under <ROOT>/images.
Example:
<ROOT>
/* Contains Documents */
/
/* Contains GPL/Changelog & Readme */
/docs
/* Contains All library files */
/lib
/* Contains All Class Files */
/lib/class
/* Contains All Modules not written in house */
/modules/foomodule
/* Contains All HTML templates */
/templates
/* Contains documents that are not directly accessed, AJAX/XML-RPC and the like */
/server
/* Contains All Images */
/images
/* Contains All Images for Reservations */
/images/reservation
/* Contains All commandline scripts */
/bin
</ROOT>
When naming files in order to make it easy for others to figure out their purpose they should follow the following naming conventions. All PHP files should end in a .php extension, all lower case. Library files should end in .lib.php. All PHP classes should be in their own distinct files which end in .class.php, except for abstract classes which end in .abstract.php. All HTML files which are conditionally included from other PHP scripts should end in .inc.php. The name of the file should represent what is contained within. Templates should match the function that calls them. See the examples below:
/* Example document */
/user.php
/* Example User { .... } Class File */
/lib/class/user.class.php
/* Example Library File */
/lib/general.lib.php
/* Example Template file for show_user() */
/templates/show_user.inc.php
Special attention must be paid to user input. The general assumption must be made that every attempt will be made by the user to maliciously disrupt the script, or cause data loss when submitted to a database. User Input includes information pulled from cookies which reside on the user's computer. All user input should be escaped and error checked before being used.
In order to not only ensure reliable database connections and data integrity but to account for future changes standardization of SQL statements and database calls is necessary. All SQL statements should use all capital letters for actual SQL commands and lowercase for field and table names when possible. Query statements should also always use the full name for fields for expandability. All user inputted values should be escaped and all field names should be escaped using the correct escape character
Example MySQL Query:
/* Simple Query */
SELECT * FROM `user`;
/* Complex Query */
SELECT `user`.`id`, `preferences`.`value` FROM `user`
LEFT JOIN `preferences` ON `user`.`id` = `preferences`.`user`
WHERE `user`.`username` = 'dude' AND `user`.`pass` = PASSWORD('mypassword')
ORDER BY `user`.`id`
LIMIT 5, 10;
All database queries should use Ampache's Dba wrapper rather than calling database functions directly.
<?php
// Query
$db_results = Dba::read('SELECT * FROM `user`);
return Dba::write('TRUNCATE `user`);
All PHP code written should work on PHP 5.3 or any newer version. All code should be written referencing the superglobals ($_POST, $_GET, and $_SERVER) as if 'register_globals' is off.
All file paths, and URLs should be fully qualified and yet relational. $PHP_SELF should never be used.
Example:
// Generated URL using Web Path
$link = Config::get('web_path') . '/index.php';
// Include Statement using Prefix */
require_once Config::get('prefix') . '/templates/cool.inc.php';
All HTML written for Ampache should conform to W3C's XHTML 1 Transitional standards. All user input that is to be echoed out must be sanitized before being displayed to the screen.