Table of Contents

Coding conventions - standards for OSInet-originated PHP and HTML code

The OSInet coding style is mostly the Zend Framework style, except for its indenting rules, which follow the second variant of the Whitesmiths / Symbian style with spacing set to two spaces. For HTML the coding style is banner.

Examples on this page are given in the context of a module (Drupal) or class called G2.

All code must work under error_reporting(E_ALL | E_STRICT)

Indenting

Function Declarations

OSInet Drupal PEAR ZF
private function foo($bar, $baz = 'qux') { $ret = action; return $ret; }function _g2_foo($bar, $baz = 'qux') { return action; }private function foo($bar, $baz = 'qux') { return action; }

Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate. Never use parentheses around the returned value (ZF: it can break code if a method is later changed to return by reference).

For long argument lists or long argument names, appropriate line wrapping may be used, like:

public function someFunctionWithALongName(
  $firstParamsHasALongNameToo,
  $secondParamIsAlmostWorse   = 'default',
  $notForgettingOtherDefaults = 0)
  {
  $ret = action;
  return $ret;
  }

Class Declarations

OSInet Drupal PEAR ZF
class Foo { // members }N.A: no classes?class Foo { // members }

if / then / else

OSInet Drupal PEAR ZF
if (test1 || test2) { action1; } elseif (test3 && test2) { action2; } else { defaultaction; }if (test1 || test2) { action1; } elseif (test3 && test4) { action2; } else { defaultaction; }if ((test1) || (test2)) { action1; } elseif ((test3) && (test4)) { action2; } else { defaultaction; }if (test1) { action1; } else if (test3) { action2; } else { defaultaction; }
  Control structures Control structures derived from §A.4.6.1.

Note that for ZF, the code sample supplied in the doc contradicts the doc text. Reference is made to the text. The rules and sample do not specify parenthesing for multiple tests in a clause.

For OSInet, long tests must be wrapped to align readably. Although ZF does not mention this, the line length requirement makes it likely too.

switch

OSInet Drupal PEAR ZF
switch (condition) { case 1: action1; break; case 2: action2; break; default: defaultaction; break; }switch (condition) { case 1: action1; break; case 2: action2; break; default: defaultaction; break; }switch (condition) { case 1: action1; break; case 2: action2; break; default: defaultaction; break; }switch (condition) { case 1: break; case 2: break; default: break; }

General table

Category OSInet Drupal PEAR ZF
Spacing Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls. Control statements based on the if and elseif constructs must have a single space before the opening parenthesis of the conditional,
… terminal n.a. … and a single space after the closing parenthesis.
Bracing always use curly braces even in situations where they are technically optional n.a.
… control, opening The opening brace is written on the line below the structure. n.a. The opening brace is written on the same line as the conditional statement.
… control, closing = ZF n.a. The closing brace is always written on its own line.
… classes = ZF n.a. The brace is always written on the line underneath the class name.

Function Calls

Category OSInet Drupal PEAR ZF
name to ( no space
( to arg1 no space
arg to , no space
, to arg usually 1 space. May vertically align for block-related function calls 1 space
arg to ) no space
) to ; no space

ZF rules for this are implied by the example in the A.4.5.2 section.

Arrays

Spacing, one-liner: identical Spacing, indented: Different

Note that if the line spans longer than 80 characters (often the case with form and menu declarations), each element should be broken into its own line, and indented one level. “⇒” symbols ought to be aligned.

$form['title'] = array
  (
  '#type'        => 'textfield',
  '#title'       => t('Title'),
  '#size'        => 60,
  '#maxlength'   => 128,
  '#description' => t('The title of your node.'),
  );

Additional comma: identical.

Including Code

OSInet contrib code does not support PHP4, so PHP5 structures like the new object model are standard.

This means that including can make use of the autoload mechanism, which can be more efficient under caching than using require_once with conditional content.

File formatting

Feature OSInet Drupal PEAR ZF
<% %> tags No No ? ?
<? ?> tags No No ? ?
Closing ?> No Should be omitted ? No
Indenting 2 spaces 2 spaces 4 spaces 4 spaces
Tabs No No No No
Line length as ZF unspecified ? Strive for 80
Maximum 120
Line termination \n recommended unspecified ? \n mandatory
\r and \r\n forbidden
__HALT_COMPILER() unspecified unspecified ? Forbidden, except in special install files

The rule regarding the closing ?> tag is only applicable to “program-type” PHP files, not to HTML pages with embedded PHP, which are mostly out of the scope of these rules.

Comments, inline doc

Category OSInet Drupal PEAR ZF
Documentation format PHPDocumentor Doxygen ? PHPDocumentor
File header like ZF, but
  • use CeCill 2.0 license if possible
  • @package and @subpackage tags to group files
  • see tag to cross-refer elements
  • @version tag can use other VCS' equivalents to CVS' $Id$
// $Id$
        
use GPL 2.0 license for core and preferably GPL 2.0 for contrib too
? /** * Short description for file * * Long description for file (if any)... * * LICENSE: Some license information * * @copyright 2005 Zend Technologies * @license http://www.zend.com/license/3_0.txt PHP License 3.0 * @version CVS: $Id:$ * @link http://dev.zend.com/package/PackageName * @since File available since Release 1.2.0 */
File header for class file as ZF, except @version, use $Id$ N.A.: no classes ? /** * Short description for class * * Long description for class (if any)... * * @copyright 2005 Zend Technologies * @license http://www.zend.com/license/3_0.txt PHP License 3.0 * @version Release: @package_version@ * @link http://dev.zend.com/package/PackageName * @since Class available since Release 1.2.0 * @deprecated Class deprecated in Release 2.0.0 */
Function header as ZF unspecified ?
  • Textual description
  • all @param
  • @return
  • @throws if the function throws an exception
  • @access now obsoleted by visibility attributes

Using CVS

Identical

Additional rule: modules must define a constant containing the version information to be displayed on the module settings page. See the rules for constants below.

Example URLs

Identical

Naming Conventions

General

Element OSInet Drupal PEAR ZF
Functions as ZF g2_get_element_by_id() ? getElementById()
Function scope as ZF No classes, so use "<module_name>_" as a namespace to avoid name collision ? Floating functions are discouraged. Use a static class.
Accessors as ZF N.A.: no classes ? getSomeField
setSomeField
Design patterns as ZF unspecified ? Include name of pattern in the name of the method, where practical
Constants class G2 { const SOME_CONSTANT = 'foo'; } define('G2_SOME_CONSTANT', 'foo'); ? class G2 { const SOME_CONSTANT = 'foo'; }
Class fields private _someFieldOne; protected _someFieldTwo; public someFieldThree; PHP4 pseudo-private field: _some_field ? private _someFieldOne; protected _someFieldTwo; public someFieldThree;
Global variables no specific rule _g2_some_variable ? no specific rule
Code files
  • Drupal components: as Drupal
  • elsewhere: as ZF
  • Module: .module
  • Module install: .install
  • Themes:
    • Plain PHP: .theme
    • PHPTemplate: .tpl.php
  • Includes: .inc
?
  • all files containing PHP code must bear the .php extension
  • the file containing class Foo must be named Foo.php
Documentation
  • Standard files: LICENSE.txt
  • Specific files:
    • CamelCaps.txt
    • Allowed text formats:
      • txt (UTF8)
      • PDF
      • OpenDocument
    • Allowed image formats:
      • SVG, SVGZ
      • PNG, including Fireworks
      • JPG
LICENSE.txt ? ?

Variables

Variables naming following the rules for functions and methods. Exceptions:

Functions and Methods

Constants

As of 01/01/2007, see table above. Note that the PHP builtins “null”, “true”, and “false” are lowercase, unlike constants from user code.

Previously, the format was:

define('G2VERSION', '$Id');

This style of coding is now considered obsolete (even under Drupal conventions, the constant should be named G2_VERSION, not G2VERSION), and should be replaced when preparing module versions for Drupal 6 by class constants like G2::VERSION, or more generally Foo::SOME_CONSTANT :

class G2
  {
  // don't forget the PHPdoc here
  const VERSION = '$Id$';
  }

Drupal-specific: Naming functions and constants within modules

// don't forget the PHPdoc comments here
class My_Module
  {
  // and here
  const SOME_CONSTANT = 'bar';
 
  // ... and here too
  static public function foo($op)
    {
    // do something and return
    }
  }
 
// ..which can be invoked as:
My_Module::foo(My_Module::SOME_CONSTANT);