Login / Status
developer.Resource
Home . Documentation . Document Library . Core Documentation
Sponsors
hosted by punkt.deTYPO3 and Open Source Magazine

1.3. PHP file formatting

General requirements to PHP files

PHP tags

Each PHP file in TYPO3 must use full PHP tags. There must be exactly one pair of opening and closing tags (no closing and opening tags in the middle of the file). Example:

<?php
// File content goes here
?>

There must be no empty lines after the closing PHP tag. Empty lines after closing tags break output compression in PHP and/or result in AJAX errors.

Line breaks

TYPO3 uses Unix line endings (\n, PHP chr(10)). If a developer uses Windows or Mac OS X platform, the editor must be configured to use Unix line endings.

Line length

Line length is limited to 80 characters. Longer lines should be split to several lines. Each line fragment starting from the second must be indented with one or more tab characters. Example:

$rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid, title', 'pages',
'pid=' . $this->fullQuoteStr($this->pid, 'pages') .
$this->cObj->enableFields('pages'), '', 'title');

In certain cases splitting lines exactly at 80 characters is not feasible. In this case lines can be longer but such practice is discouraged.

Whitespace and indentation

TYPO3 uses tab characters to indent source code. One indentation level is one tab.

There must be no white spaces in the end of a line. This can be done manually or using a text editor that takes care of this (see section “Settings for editors” on page 16).

Spaces must be added:

  1. on both sides of string, arithmetic, assignment and other similar operators (for example, ., =, +, -, ?, :, *, etc)

  2. after commas

  3. in single line comments after the comment sign (double slash)

  4. after asterisks in multiline comments

Character set

TYPO3 PHP files use iso-8859-1 character set.

All XML files use UTF-8 character set.

File structure

TYPO3 files use the following structure:

  1. Opening PHP tag

  2. Copyright notice

  3. File information block (with optional function index) in phpDoc format

  4. Included files

  5. Class information block in phpDoc format

  6. PHP class

  7. XCLASS declaration

  8. Optional module execution code (for example, in eID classes)

  9. Closing PHP tag

The following sections discuss each of these parts.

Copyright notice

TYPO3 is released under the terms of GNU General Public License version 2 or any later version. The copyright notice with a reference to the GPL must be included at the top of every TYPO3 PHP class file. user_ files must have this copyright notice as well. Example:

<?php
/***************************************************************
*  Copyright notice
*
*  (c) YYYY Your name here (your@email.here)
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*  A copy is found in the textfile GPL.txt and important notices to the license
*  from the author is found in LICENSE.txt distributed with these scripts.
*
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

This notice may not be altered except for the year, author name and author e-mail.

File information block

File information block follows the copyright statement and provides basic information about the file. It should include file name, description of the file and information about the author (or authors). Example:

/**
 * class.tx_myext_pi1.php
 *
 * Provides XYZ plugin implementation.
 *
 * $Id: class.tx_myext_pi1.php 9514 2008-07-23 17:06:12Z john_doe $
 *
 * @author John Doe <john.doe@example.com>
 */

The example above uses SVN $Id$ meta keyword. SVN will expand it to a full version string when the file is committed.

The file information block can also contain the optional function index. This index is created and updated by the extdeveval extension.

Included files

Files are included using require_once function. All TYPO3 files must use absolute paths in calls to require_once. There are two ways to obtain the path to the included file:

  1. Use one of the predefined TYPO3 constants: PATH_tslib, PATH_t3lib, PATH_typo3, PATH_site. The first three contain absolute paths to the corresponding TYPO3 directories. The last constant contains absolute path to the TYPO3 root directory. Example:

require_once(PATH_tslib . 'class.tslib_pibase.php');

  1. Use t3lib_extMgm::extPath() function. This function accepts two arguments: extension key and path to the included file. The second argument is optional but recommended to use. Examples:

require_once(t3lib_extMgm::extPath('lang', 'lang.php'));

require_once(t3lib_extMgm::extPath('lang') . 'lang.php');

Always use one of these two ways to include files. This is required to include files even from the current directory. Some installations do not have the current directory in the PHP include path and require_once without a proper path will result in fatal PHP error.

Class information block

Class information block is similar to the file information block and describes the class in the file. Example:

/**
 * This class provides XYZ plugin implementation.
 *
 * @author John Doe <john.doe@example.com>
 * @author Jane Doe <jane.doe@example.com>
 */

PHP class

PHP class follows the Class information block. PHP code must be formatted as described in chapter “PHP syntax formatting” on page 9.

XCLASS declaration

The XCLASS declaration must follow the PHP class. The format of the XCLASS is very important. No spaces can be added or removed, no reformatting can be done to the declaration. If the formatting is changed, the TYPO3 Extension Manager will complain about a missing XCLASS declaration.

The XCLASS declaration must include proper path to the current class file. The following example assumes that extension key is myext, file name is class.tx_myext_pi1.php and file is located in the pi1 subdirectory of the extension:

if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/myext/pi1/class.tx_myext_pi1.php']){

include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/myext/pi1/class.tx_myext_pi1.php']);

}

Optional module execution code

Module execution code instantiates the class and runs its method(s). Typically this code can be found in eID scripts and old Backend modules. Here is how it may look like:

$controller = t3lib_div::makeInstance('tx_myext_ajaxcontroller');
$controller->main();

This code must appear after the XCLASS declaration. $SOBE is traditional but not required name.

PHP syntax formatting

Identifiers

All identifiers must use camelCase and start with a lower case letter. Underscore characters are not allowed. Abbreviations should be avoided. Examples of good identifiers:

$goodName
$anotherGoodName

Examples of bad identifiers:

$BAD_name
$unreasonablyLongNamesAreBadToo
$noAbbrAlwd

Identifier names must be descriptive. However it is allowed to use traditional integer variables like $i, $j, $k in for loops. If such variables are used, their meaning must be absolutely clear from the context where they are used.

The same rules apply to functions and class methods. Examples:

protected function getFeedbackForm()
public function processSubmission()

Class constants should be clear about what they define. Correct:

const USERLEVEL_MEMBER = 1;

Incorrect:

const UL_MEMBER = 1;

Variables on the global scope may use upper case and underscore characters.

Examples:

$TYPO3_CONF_VARS
$TYPO3_DB

Comments

Comments in the code are highly welcome and recommended. Inline comments must precede the commented line and be indented by one tab. Example:

protected function processSubmission() {

// Check if user is logged in

if ($GLOBALS['TSFE']->fe_user->user['uid']) {
...
}
}

Class constants and variable comments should follow PHP doc style and precede the variable. Variable type must be specified for non–trivial types and optional for trivial types. Example:

/** Number of images submitted by user */
protected $numberOfImages;
/**
 * Local instance of tslib_cObj class
 *
 * @var tslib_cObj
 */
protected $localCobj;

Single line comments are allowed when there is no type declaration for the class variable or constant.

If variable can hold value of different types, use mixed as type.

Debug output

During development it is allowed to use debug() or t3lib_div::debug() function calls to produce debug output. However all debug statements must be removed (removed, not commented!) before committing the code to the Subversion repository.

Curly braces

Usage of opening and closing curly braces is mandatory in all cases where they can be used according to PHP syntax (except case statements).

The opening curly brace is always on the same line as the preceding construction. There must be a space (not a tab!) before the opening brace. The opening brace is always followed by a new line.

The closing curly brace must start on a new line and be indented to the same level as the construct with the opening brace. Example:

protected function getForm() {
if ($this->extendedForm) {
// generate extended form here
} else {
// generate simple form here
}
}

The following is not allowed:

protected function getForm()
{
if ($this->extendedForm) { // generate extended form here
} else {
// generate simple form here
}
}

Conditions

Conditions consist from if, elseif and else keywords. TYPO3 code must not use the else if construct.

The following is the correct layout for conditions:

if ($this->processSubmission) {
// Process submission here
} elseif ($this->internalError) {
// Handle internal error
} else {
// Something else here
}

Here is an example of the incorrect layout:

if ($this->processSubmission) {
// Process submission here
}
elseif ($this->internalError) {
// Handle internal error
} else { // Something else here

It is recommended to create conditions so that shortest block goes first. For example:

if (!$this->processSubmission) {
// Generate error message, 2 lines
} else {
// Process submission, 30 lines
}

If the condition is long, it must be split into several lines. Each condition on the line starting from the second should be indented with a two or more indents relative to the first line of the condition:

if ($this->getSomeCodition($this->getSomeValiarble()) &&
$this->getAnotherCondition()) {
// Code follows here
}

Ternary conditional operator must be used only if it has two outcomes. Example:

$result = ($useComma ? ',' : '.');

Wrong usage of ternary conditional operator:

$result = ($useComma ? ',' : $useDot ? '.' : ';');

Assignment in conditions should be avoided. However if it makes sense to do assignment in condition, it should be surrounded by the extra pair of brackets. Example:

if (($fields = $GLOBALS['TYPO3_DB']->sql_fetch_result($res))) {
// Do something
}

The following is allowed but not recommended:

if (false !== ($fields = $GLOBALS['TYPO3_DB']->sql_fetch_result($res))) {
// Do something
}

The following is not allowed (missing the extra pair of brackets):

while ($fields = $GLOBALS['TYPO3_DB']->sql_fetch_result($res)) {
// Do something
}

Switch

case statements are indented with a single indent (tab) inside the switch statement. The code inside the case statements is further indented with a single indent. The break statement is aligned with the code. Only one break statement is allowed per case.

The default statement must be the last in the switch and must not have a break statement.

If one case block has to pass control into another case block without having a break, there must be a comment about it in the code.

Examples:

switch ($useType) {
case 'extended':
$content .= $this->extendedUse();
// Fall through
case 'basic':
$content .= $this->basicUse();
break;
default:
$content .= $this->errorUse();
}

Loops

The following loops can be used:

  1. do

  2. while

  3. for

  4. foreach

The use of each is not allowed in loops.

for loops must contain only variables inside (no function calls). The following is correct:

$size = count($dataArray);
for ($element = 0; $element < $size; $element++) {
// Process element here
}

The following is not allowed:

for ($element = 0; $element < count($dataArray); $element++) {
// Process element here

}

do and while loops must use extra brackets if assignment happens in the loop:

while (($fields = $GLOBALS['TYPO3_DB']->sql_fetch_result($res))) {
// Do something
}

Strings

All strings must use single quotes. Double quotes are allowed only to create the new line character (“\n”).

String concatenation operator must be surrounded by spaces. Example:

$content = 'Hello ' . 'world!';

However the space after the concatenation operator must not be present if the operator is the last construction on the line. See the section about white spaces on page 7 for more information.

Variables must not be embedded into strings. Correct:

$content = 'Hello ' . $userName;

Incorrect:

$content = “Hello $userName”;

Multiline string concatenations are allowed. Line concatenation operator must be at the end of the line. Lines starting from the second must be indented relative to the first line. It is recommended to indent lines one level from the start of the string on the first level:

$content = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' .
'Donec varius libero non nisi. Proin eros.';

PHP5 features

The use of PHP5 features is strongly recommended for extensions and mandatory for the TYPO3 core versions 4.2 or greater.

Class functions must have access type specifier: public, protected or private. Notice that private may prevent XCLASSing of the class. Therefore private can be used only if it is absolutely necessary.

Class variables must use access specifier instead of var keyword.

Type hinting must be used when function expects array or an instance of a certain class. Example:

protected function executeAction(tx_myext_action& $action, array $extraParameters) {
// Do something
}

Static functions must use static keyword. This keyword must be the first keyword in the function definition:

static public function executeAction(tx_myext_action& $action, array $extraParameters) {
// Do something
}

abstract keyword also must be on the first position in the function declaration:

abstract protected function render();

Global variables

Use of global is not recommended. Always use $GLOBALS['variable'].

Functions

If a function returns a value, it must always return it. The following is not allowed:

function extendedUse($enabled) {
if ($enabled) {
return 'Extended use';
}
}

The following is the correct behavior:

function extendedUse($enabled) {
$content = '';
if ($enabled) {
$content = 'Extended use';
}
return $content;
}

In general there should be a single return statement in the function (see the preceding example). However a function can return during parameter validation before it starts its main logic. Example:

function extendedUse($enabled, tx_myext_useparameters $useParameters) {
// Validation
if (count($useParameters->urlParts) < 5) {
return 'Parameter validation failed';
}
// Main functionality
$content = '';
if ($enabled) {
$content = 'Extended use';
} else {
$content = 'Only basic use is available to you!';
} 
return $content;
}

Functions should not be long. “Long” is not defined in terms of lines. General rule is that function should fit into 2/3 of the screen. This rule allows small changes in the function without splitting the function further.

Using phpDoc

phpDoc is used for documenting source code. Typically TYPO3 code uses the following phpDoc keywords:

  1. @author

  2. @access

  3. @global

  4. @param

  5. @package

  6. @return

  7. @see

  8. @subpackage

  9. @var

For more information on phpDoc see the phpDoc web site at http://www.phpdoc.org/

TYPO3 requires that each class, function and method is documented with phpDoc. For information on phpDoc with use in classes see “Class information block” on page 9.

Functions should have parameters and return type documented. Example:

/** * Initializes the plugin. Checks the configuration and substitutes defaults for missing values. * @paramarray$confPlugin configuration from TypoScript * @returnvoid * @seetx_myext_class:anotherFunc() */protected function initialize(array $conf) {

// Do something
}

Notice the use of void when function does not return a value.

The ChangeLog file

TYPO3 core has a ChangeLog file where all changes are recorded. This file is committed to the SVN together with the change.

Each entry in the ChangeLog file has the following format:

  1. Information about the date of the change (YYYY-mm-dd), author name and author's e-mail address. These three pieces of information are separated strictly by two spaces (no tabs!)

  2. Empty line

  3. One or more lines describing the change. Each such line is indented by a single tab

  4. Empty line

Line that describes the change consists from the following parts:

  1. Asterisk character

  2. Type of the change (“Fixed bug” or “Added feature”)

  3. Bug tracker issue id (“#12345”)

  4. A colon

  5. Bug tracker issue title or, if needed, a more meaningful title that describes the change (“great feature for TYPO3”)

  6. Optional “thanks to” message of the patch was submitted by the contributor

In some cases the line can have free format. This applies to non–functional changes, like “Formatting change” or “Fixed copyright dates”).

Here is an example of the ChangeLog entry:

2009-01-06  John Doe  <john@doe.com>
* Fixed bug #12345: typolink does not take XYZ into account
* Added feature #12345: Google sitemap in the TYPO3 core (thanks to Jane Doe)

ChangeLog file updates are mandatory for every change in the TYPO3 core. Extension authors are strongly recommended to use such file with the same format in their extensions.