Table of Contents
Coding Standards are an important factor for achieving a high code quality. A common visual style, naming conventions and other technical settings allow us to produce a homogenous code which is easy to read and maintain. However, not all important factors can be covered by rules and coding standards. Equally important is the style in which certain problems are solved programmatically - it's the personality and experience of the individual developer which shines through and ultimately makes the difference between technically okay code or a well considered, mature solution.
These guidelines try to cover both, the technical standards as well as giving incentives for a common development style. These guidelines must be followed by everyone who creates code for the FLOW3 core. Because TYPO3 is based on UNKNOW3, it follows the same principles - therefore, whenever we mention FLOW3 in the following sections, we equally refer to TYPO3. We hope that you feel encouraged to follow these guidelines as well when creating your own packages and FLOW3 based applications.
The visual style of programming code is very important. In the TYPO3 project we want many programmers to contribute, but in the same style. This will help us to:
Easily read/understand each others code and consequently easily spot security problems or optimization opportunities
It is a signal about consistency and cleanliness, which is a motivating factor for programmers striving for excellence
Some people may object to the visual guidelines since everyone has his own habits. You will have to overcome that in the case of FLOW3; the visual guidelines must be followed along with coding guidelines for security. We want all contributions to the project to be as similar in style and as secure as possible.
Nearly any PHP file in FLOW3 contains exactly one class and
does not output anything if it is called directly. Therefore you start
you file with a <?php tag and end it with the closing
?>.
Every file must contain a header stating copyright and licensing information
Because it is likely that more than one person will work on a class in the long run, we recommend adding a copyright statement like “Copyright belongs to the respective authors” and add yourself to the list of authors for the methods you implemented.
If you modify a library you must document what you have changed (GPL requirement). Add your name as author / co-author to these modifications.
The importance of the header is primarily to state that the code is GPL'ed. And remember only GPL compatible software is allowed to interface with FLOW3 (according to GPL itself).
The copyright header itself must not start with
/**, as this may confuse documentation
generators!
Example 5.1. The FLOW3 standard file header
<?php declare(encoding = 'utf-8'); /* * * This script is part of the TYPO3 project - inspiring people to share! * * * * TYPO3 and UNKWON3 are free software; you can redistribute them and/or * * modify them under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * * This script is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- * * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * * Public License for more details. * * */
Code lines are of arbitrary length, no limitations to 80 characters or something similar (wake up, graphical displays has been available for decades now...)
Lines end with a newline a.k.a chr(10) - UNIX
style
Indentation is done with tabs - and not spaces! The beginning of a line is the only place where tabs are used, in all other places use spaces. Always trim whitespace off the end of a line.
Here's a code snippet which shows the correct usage of tabs and spaces:
Example 5.2. Correct use of tabs and spaces
» /*‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧*
» ‧*‧Some‧comment‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧*
» ‧*‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧*/
» /**
» ‧*‧Returns‧the‧name‧of‧the‧currently‧set‧context.
» ‧*
» ‧*‧@return‧string‧Name‧of‧the‧current‧context
» ‧*‧@author‧Robert‧Lemke‧<robert@typo3.org>
» ‧*/
» public‧function‧getContext()‧{
» » return‧$this->context;
» }
There seem to be very passionate opinions about whether TABs or spaces should be used for indentation of code blocks in the scripts. If you'd like to read more about this religious discussion, you find some nice arguments in the Joels on Software forum.
Naming is a repeatedly undervalued factor in the art of software development. Although everybody seems to agree on that nice names are a nice thing to have, most developers choose cryptic abbreviations in the end (to save some typing). Beware that we TYPO3 core developers are very passionate about naming (some people call it fanatic, well ...). In our opinion spending 15 minutes (or more ...) just to find a good name for a method is well spent time! There are zillions of reasons for using proper names and in the end they all lead to better readable, manageable, stable and secure code.
As a general note, english words (or abbreviations if neccessary) must be used for all class names, method names, comments, variables names, database table and field names. Although PHP6 allows for using funny japanese, tibetian or don't-know-what characters, the consensus is that english is much better to read for the most of us.
If acronyms or abbreviations are embedded in names, keep them
in the case they usually are, i.e. keep URL
uppercase, also when used in a method name like
getURLForLink(),
ACMEManager etc.
All package names are written in UpperCamelCase. In order to avoid problems with different filesystems, only the characters a-z, A-Z and 0-9 are allowed for package names – don't use special characters.
Only the characters a-z, A-Z and 0-9 are allowed for class names – don't use special characters. The underscore sign "_" is allowed for separating the package name from the sub-package or component name from the sub-component name and so on.
All class names are written in
UpperCamelCase, all uppercase names are allowed
for well established abbreviations. Class names must be nouns, never
adjectives.
A class name must start with the prefix "F3_". The name of the package containing the class follows, parts of the package hierarchy are seperated with underscores.
The name of abstract classes should start with the word "Abstract".
A few examples follow:
Example 5.3. Correct naming of classes
F3_FLOW3_Component
F3_FLOW3_Component_Manager
F3_MyPackage_MyComponent_MySubComponent
F3_MyPackage_MyComponent_MyHTMLParser
F3_Foo_Controller_Default
F3_MyPackage_MyComponent_AbstractLogger
Example 5.4. Incorrect naming of classes
myClass
F3_Urlwrapper
someComponent_classname
F3_MyPackage_MyComponentMySubComponent
F3_Foo_Controller_DefaultController
Only the characters a-z, A-Z and 0-9 are allowed for interface names – don't use special characters. The underscore sign "_" is allowed for separating the package name from the interface name from the sub-component name and so on.
All interface names are written in
UpperCamelCase, all uppercase names are allowed
for well established abbreviations. Interface names must be adjectives
or nouns and have the Interface suffix.
An interface name must start with the prefix "F3_". The name of the package containing the interface follows, parts of the package hierarchy are seperated with underscores. A few examples follow:
Example 5.5. Correct naming of interfaces
F3_FLOW3_Component_Interface
F3_FLOW3_Component_ManagerInterface
F3_MyPackage_MyComponent_MySubComponentInterface
F3_MyPackage_MyComponent_MyHTMLParserInterface
Example 5.6. Incorrect naming of interfaces
myInterface
F3_Urlwrapper
IsomeComponent_classname
F3_FLOW3_Component_Manager_Interface
Exception naming basically follows the rules for naming classes.
There are two possible types of exceptions: Generic exceptions and
specific exceptions. Generic exceptions should be named "Exception"
preceeded by their namespace. Specific exceptions should reside in their
own sub-namespace and must not contain the word
Exception.
Example 5.7. Correct naming of exceptions
F3_FLOW3_Component_Exception
F3_FLOW3_Component_Exception_InvalidClassName
F3_MyPackage_MyComponent_Exception
F3_MyPackage_MyComponent_Exception_OutOfCoffee
All method names are written in lowerCamelCase, all uppercase names are allowed for well established abbreviations. In order to avoid problems with different filesystems, only the characters a-z, A-Z and 0-9 are allowed for method names – don't use special characters.
Make method names descriptive, but keep them concise at the same
time. Constructors must always be called
__construct(), never use the class name as a method
name.
A few examples:
Example 5.8. Correct naming of methods
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYMCALoudly()
__construct()
Variable names are written in lowerCamelCase
and should be
self-explaining
not shortened beyond recognition, but rather longer if it makes their meaning clearer
The following example shows two variables with the same meaning but different naming. You'll surely agree the longer versions are better (don't you ...?).
As a special exception you may use variable names like
$i, $j and $k
for numeric indexes in for loops if it's clear what
they mean on the first sight. But even then you might want to avoid
them.
All constant names are written in UPPERCASE.
This includes TRUE, FALSE and
NULL. Words can be separated by underscores - you
can also use the underscore to group constants thematically:
Example 5.11. Correct naming of constants
STUFF_LEVEL
COOLNESS_FACTOR
PATTERN_MATCH_EMAILADDRESS
PATTERN_MATCH_VALIDHTMLTAGS
It is, by the way, a good idea to use constants for defining regular expression patterns (as seen above) instead of defining them somewhere in your code.
The directory layout used for FLOW3 is shown below. Conventions for file names will be explained in it's own section below.
All directory names are
UpperCamelCase.
ConfigurationThis directory contains the configuration files for the system. There should be only very few and small files here, as the majority of the configuration should be stored in the content repository.
FileCacheThe FileCache directory holds copies of
files stored in the content repository. They are stored locally
(as seen from the webserver) to speed up delivery. The filecache
directory itself contains only sub-directories which in turn hold
either files or again sub-directories.
PublicThe Public directory will always
exist and stores copies if files for which no access
restriction exists.
PackagesPackages can put their cache content below this directory, the next level directories are named after the package, in those the packages can reign freely.
IntranetThis is an example for a folder that contains files accessible only for requests authorized to fetch content from the "intranet" scope.
PackagesThis directory contains sub-directories for all packages installed with the system. This includes packages delivered with the TYPO3 distribution as well as locally installed packages. Package directories contain further directories, some of which are mandatory.
[Package]ClassesThis directory contains the actual code for the package. Package authors are free to add (only!) class or interface files directly to this directory or to add another level to organize the content if necessary. All classes or interfaces below this directory are handled by the autolading mechanism and will be registered with the component manager automatically (and will thus be considered "components").
DocumentationHolds the package documentation. Please refer to the Documentor's Guide for more details about the directories and files within this directory.
MetaContains meta data about the package
PackageInfo.xmlContains the basic information about the package, such as title, description, author, constraints, ...
ResourcesContains static resources the package needs, such as library code, template files, graphics, ...
MediaThis directory holds images, PDF, Flash, CSS
and other files that will be delivered to the client
directly without further processing. The content of
this directory will be copied into the content
repository and propagated to the
FileCache automatically by the
package manager.
TemplatesTemplate files used by the package should go here. If a user wants to modify the template it will end up elsewhere and should be pointed to by some configuration setting.
PHPShould hold any PHP code that is an external library, PEAR or eZ component, should not be handled by the component manager (at least not by default), is of procedural nature or doesn't belong into the classes directory for any other reason.
JavaShould hold any Java code needed by the
package. Repeat and rinse for Smalltalk, Modula,
Pascal, ... ;)
More directories can be added as needed.
TestsHolds the unit tests for the package
In addition to the directory naming rules laid out above there are also rules for naming the files inside those directories, of course. Here we go:
All file names are UpperCamelCase.
Class and interface files are named according to the class or interface they represent
Each file must contain only one class or interface
Names of configuration files must names start with
configuration_
Names of files containing code for unit tests must be the same as the class which is tested, appended with "Test.php".
Here are some examples:
Example 5.12. File naming in FLOW3
F3_TemplateEngine_TemplateEngineInterface.php
Contains the interface
F3_TemplateEngine_TemplateEngineInterface
which is part of the package
F3_TemplateEngine
F3_Error_RuntimeException.php
Contains the
F3_Error_RuntimeException being a part
of the package F3_Error
F3_DataAccess_Manager.php
Contains class
F3_DataAccess_Manager which is part of
the package F3_DataAccess
F3_FLOW3_Package_Manager.php
Contains the class
F3_FLOW3_Package_Manager which is
part of the package F3_FLOW3
F3_FLOW3_Package_ManagerTest.php
Contains the class
F3_FLOW3_Package_ManagerTest which
is a test case for PHPUnit.
In general, we use single quotes to enclose literal strings:
If the string itself contains single quotes or apostrophes, we use double quotes:
Example 5.14. String literals enclosed by double quotes
$message = "'Kasper' is the name of the friendly ghost.";
If you'd like to insert values from variables, we recommend to concatenate strings or use double quotes in the following form:
Example 5.15. Variable substitution
$message = 'Hey ' . $name . ', you look ' . $look . ' today!'; $message = "Hey $name, you look $look today!";
As you've seen in the previous example, we concatenate strings by using the dot operator. A space must be inserted before and after the dot for better readability:
You may break a string into multiple lines if you use the dot operator. You'll have to indent each following line to mark them as part of the value assignment:
There needs to be one space between the
if keyword and the opening brace "("
...
Example 5.19. if statements
if ($something || $somethingElse) {
doThis();
} else {
doSomethingElse();
}
if (allGoesWrong()) throw new Exception('Hey, all went wrong!');
if (weHaveALotOfCriteria() &&
notEverythingFitsIntoOneLine() ||
youJustTendToLikeIt()) {
doThis();
} else {
...
}