cvs: peardoc /en/chapters standards.xml
[email protected] ("Christian Weiske")
| Newsgroups | php.pear.doc |
|---|---|
| Message-ID | <cvscweiske1241470603@cvsserver> |
cweiske Mon May 4 20:56:43 2009 UTC
Modified files:
/peardoc/en/chapters standards.xml
Log:
Integrate CS enhancements RFC into CS
cweiske-20090504205643.txt
(text/plain, 24.2 KB)
http://cvs.php.net/viewvc.cgi/peardoc/en/chapters/standards.xml?r1=1.73&r2=1.74&diff_format=u
Index: peardoc/en/chapters/standards.xml
diff -u peardoc/en/chapters/standards.xml:1.73 peardoc/en/chapters/standards.xml:1.74
--- peardoc/en/chapters/standards.xml:1.73 Mon May 4 20:19:30 2009
+++ peardoc/en/chapters/standards.xml Mon May 4 20:56:42 2009
@@ -1,9 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
-<chapter xmlns="http://docbook.org/ns/docbook" version="lillet" xml:id="standards">
+<chapter xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="lillet" xml:id="standards"
+>
<info>
<title>Coding Standards</title>
</info>
-
+
<note>
<simpara>
The PEAR Coding Standards apply to code that is part of the official
@@ -12,7 +15,7 @@
and maintainable by most of PEAR folks.
</simpara>
</note>
-
+
<para>
The original coding standards have been adjusted several times through
RFCs:
@@ -26,6 +29,11 @@
</listitem>
<listitem>
<para>
+ <link linkend="rfc.error-handling">Error Handling Guidelines for PHP5 packages</link>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<link linkend="rfc.header-comments">Header Comment Blocks</link>
</para>
</listitem>
@@ -41,24 +49,24 @@
</para>
</listitem>
</itemizedlist>
-
+
<para>
- Those RFCs have only partly been integrated into this document.
+ Those RFCs have been integrated into this document.
</para>
-
+
<note>
<para>
The <link linkend="pear2cs.rules">PEAR2 Coding Standards</link> define
several other rules that have to be followed once PEAR2 is in place.
</para>
</note>
-
-
+
+
<section xml:id="standards.indenting">
<info>
<title>Indenting and Line Length</title>
</info>
-
+
<para>
Use an indent of 4 spaces, with no tabs. This helps to avoid problems
with diffs, patches, CVS history and annotations.
@@ -93,10 +101,11 @@
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&url.linelength.paulmjones;">some thoughts</link> about
that limit.
</para>
+
</section>
<section xml:id="standards.control"><info><title>Control Structures</title></info>
-
+
<para>
These include if, for, while, switch, etc. Here is an example if
statement, since it is the most complicated of them:
@@ -142,10 +151,101 @@
]]>
</programlisting>
</para>
+
+
+ <section xml:id="standards.control.splitlongstatements">
+ <title>Split long if statements onto several lines</title>
+
+ <para>Long if statements may be split onto several lines when the
+ character/line limit would be exceeded. The conditions have to be
+ positioned onto the following line, and indented 4 characters. The logical
+ operators (<literal>&&</literal>, <literal>||</literal>, etc.)
+ should be at the beginning of the line to make it easier to comment (and
+ exclude) the condition. The closing parenthesis and opening brace get
+ their own line at the end of the conditions.</para>
+
+ <para>Keeping the operators at the beginning of the line has two
+ advantages: It is trivial to comment out a particular line during
+ development while keeping syntactically correct code (except of course the
+ first line). Further is the logic kept at the front where it's not
+ forgotten. Scanning such conditions is very easy since they are aligned
+ below each other.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+if (($condition1
+ || $condition2)
+ && $condition3
+ && $condition4
+) {
+ //code here
+}
+?>]]></programlisting>
+
+ <para>The first condition may be aligned to the others.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+if ( $condition1
+ || $condition2
+ || $condition3
+) {
+ //code here
+}
+?>]]></programlisting>
+
+ <para>The best case is of course when the line does not need to be split.
+ When the if clause is really long enough to be split, it might be better
+ to simplify it. In such cases, you could express conditions as variables
+ an compare them in the <literal>if()</literal> condition. This has the
+ benefit of "naming" and splitting the condition sets into smaller, better
+ understandable chunks:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$is_foo = ($condition1 || $condition2);
+$is_bar = ($condition3 && $condtion4);
+if ($is_foo && $is_bar) {
+ // ....
+}
+?>]]></programlisting>
+
+ <note>
+ <para>There were suggestions to indent the parantheses "groups" by 1
+ space for each grouping. This is too hard to achieve in your coding
+ flow, since your tab key always produces 4 spaces. Indenting the if
+ clauses would take too much finetuning.</para>
+ </note>
+ </section>
+
+
+ <section xml:id="standards.control.ternaryoperators">
+ <title>Ternary operators</title>
+
+ <para>The same rule as for if clauses also applies for the <link
+ xlink:href="http://php.net/ternary">ternary operator</link>: It may be
+ split onto several lines, keeping the question mark and the colon at the
+ front.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$a = $condition1 && $condition2
+ ? $foo : $bar;
+
+$b = $condition3 && $condition4
+ ? $foo_man_this_is_too_long_what_should_i_do
+ : $bar;
+?>]]></programlisting>
+ </section>
+
</section>
- <section xml:id="standards.funcalls"><info><title>Function Calls</title></info>
-
+
+ <section xml:id="standards.funcalls">
+ <info>
+ <title>Function Calls</title>
+ </info>
+
<para>
Functions should be called with no spaces between the function
name, the opening parenthesis, and the first parameter; spaces
@@ -170,10 +270,125 @@
]]>
</programlisting>
</para>
+
+ <para>
+ To support readability, parameters in subsequent calls to the same
+ function/method may be aligned by parameter name:
+ </para>
+ <programlisting role="php"><![CDATA[<?php
+
+$this->callSomeFunction('param1', 'second', true);
+$this->callSomeFunction('parameter2', 'third', false);
+$this->callSomeFunction('3', 'verrrrrrylong', true);
+?>]]></programlisting>
+
+ <section xml:id="standards.funcalls.splitfunccall">
+ <title>Split function call on several lines</title>
+
+ <para>The CS require lines to have a maximum length of 80 chars. Calling
+ functions or methods with many parameters while adhering to CS is
+ impossible in that cases. It is allowed to split parameters in
+ function calls onto several lines.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$this->someObject->subObject->callThisFunctionWithALongName(
+ $parameterOne, $parameterTwo,
+ $aVeryLongParameterThree
+);
+?>]]></programlisting>
+
+ <para>Several parameters per line are allowed. Parameters need to be
+ indented 4 spaces compared to the level of the function call. The opening
+ parenthesis is to be put at the end of the function call line, the closing
+ parenthesis gets its own line at the end of the parameters. This shows a
+ visual end to the parameter indentations and follows the opening/closing
+ brace rules for functions and conditionals.</para>
+
+ <para>The same applies not only for parameter variables, but also for
+ nested function calls and for arrays.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$this->someObject->subObject->callThisFunctionWithALongName(
+ $this->someOtherFunc(
+ $this->someEvenOtherFunc(
+ 'Help me!',
+ array(
+ 'foo' => 'bar',
+ 'spam' => 'eggs',
+ ),
+ 23
+ ),
+ $this->someEvenOtherFunc()
+ ),
+ $this->wowowowowow(12)
+);
+?>]]></programlisting>
+
+ <para>Nesting those function parameters is allowed if it helps to make the
+ code more readable, not only when it is necessary when the characters per
+ line limit is reached.</para>
+
+ <para>Using fluent application programming interfaces often leads to many
+ concatenated function calls. Those calls may be split onto several lines.
+ When doing this, all subsequent lines are indented by 4 spaces and begin
+ with the "<literal>-></literal>" arrow.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$someObject->someFunction("some", "parameter")
+ ->someOtherFunc(23, 42)
+ ->andAThirdFunction();
+?>]]></programlisting>
+ </section>
+
+
+ <section xml:id="standards.funcalls.alignassignments">
+ <title>Alignment of assignments</title>
+
+ <para>To support readability, the equal signs may be aligned in
+ block-related assignments:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$short = foo($bar);
+$longer = foo($baz);
+?>]]></programlisting>
+
+ <para>The rule can be broken when the length of the variable name is at
+ least 8 characters longer/shorter than the previous one:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$short = foo($bar);
+$thisVariableNameIsVeeeeeeeeeeryLong = foo($baz);
+?>]]></programlisting>
+ </section>
+
+
+ <section xml:id="standards.funcalls.splitlongassignments">
+ <title>Split long assigments onto several lines</title>
+
+ <para>Assigments may be split onto several lines when the character/line
+ limit would be exceeded. The equal sign has to be positioned onto the
+ following line, and indented by 4 characters.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$GLOBALS['TSFE']->additionalHeaderData[$this->strApplicationName]
+ = $this->xajax->getJavascript(t3lib_extMgm::siteRelPath('nr_xajax'));
+?>]]></programlisting>
+ </section>
+
</section>
- <section xml:id="standards.classdef"><info><title>Class Definitions</title></info>
-
+
+ <section xml:id="standards.classdef">
+ <info>
+ <title>Class Definitions</title>
+ </info>
+
<para>
Class declarations have their opening brace
on a new line:
@@ -191,8 +406,11 @@
</section>
- <section xml:id="standards.funcdef"><info><title>Function Definitions</title></info>
-
+ <section xml:id="standards.funcdef">
+ <info>
+ <title>Function Definitions</title>
+ </info>
+
<para>
Function declarations follow the <quote>K&R style</quote>:
<programlisting role="php">
@@ -230,10 +448,56 @@
]]>
</programlisting>
</para>
+
+ <section xml:id="standards.funcdef.splitfuncdefs">
+ <title>Split function definitions onto several lines</title>
+
+ <para>Functions with many parameters may need to be split onto several lines
+ to keep the 80 characters/line limit. The first parameters may be put onto the
+ same line as the function name if there is enough space. Subsequent
+ parameters on following lines are to be indented 4 spaces. The closing
+ parenthesis and the opening brace are to be put onto the next line, on the
+ same indentation level as the "<token>function</token>" keyword.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+function someFunctionWithAVeryLongName($firstParameter = 'something', $secondParameter = 'booooo',
+ $third = null, $fourthParameter = false, $fifthParameter = 123.12,
+ $sixthParam = true
+) {
+ //....
+?>]]></programlisting>
+ </section>
+
+ </section>
+
+
+ <section xml:id="standards.arrays">
+ <info>
+ <title>Arrays</title>
+ </info>
+
+ <para>Assignments in arrays may be aligned. When splitting array
+ definitions onto several lines, the last value may also have a trailing
+ comma. This is valid PHP syntax and helps to keep code diffs
+ minimal:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+$some_array = array(
+ 'foo' => 'bar',
+ 'spam' => 'ham',
+);
+?>]]></programlisting>
+
</section>
- <section xml:id="standards.comments"><info><title>Comments</title></info>
-
+
+ <section xml:id="standards.comments">
+ <info>
+ <title>Comments</title>
+ </info>
+
<para>
Complete inline documentation comment blocks (docblocks)
must be provided. Please read the
@@ -258,7 +522,7 @@
</section>
<section xml:id="standards.including"><info><title>Including Code</title></info>
-
+
<para>
Anywhere you are unconditionally including a class file, use
<command>require_once</command>. Anywhere you are conditionally
@@ -279,7 +543,7 @@
</section>
<section xml:id="standards.tags"><info><title>PHP Code Tags</title></info>
-
+
<para>
<emphasis>Always</emphasis> use <literal><?php ?></literal> to
delimit PHP code, not the <literal><? ?></literal> shorthand.
@@ -289,7 +553,7 @@
</section>
<section xml:id="standards.header"><info><title>Header Comment Blocks</title></info>
-
+
<para>
All source code files in the PEAR repository shall contain a
<quote>page-level</quote> docblock at the top of each file
@@ -363,7 +627,7 @@
</para>
<section xml:id="standards.header.variable"><info><title>Required Tags That Have Variable Content</title></info>
-
+
<variablelist>
<varlistentry>
<term>Short Descriptions</term>
@@ -484,7 +748,7 @@
</section>
<section xml:id="standards.header.optional"><info><title>Optional Tags</title></info>
-
+
<variablelist>
<varlistentry>
<term>@copyright</term>
@@ -538,7 +802,7 @@
</section>
<section xml:id="standards.header.order"><info><title>Order and Spacing</title></info>
-
+
<para>
To ease long term readability of PEAR source code, the
text and tags must conform to the order and spacing
@@ -548,7 +812,7 @@
</section>
<section xml:id="standards.header.version"><info><title>@package_version@ Usage</title></info>
-
+
<para>
There are two ways to implement the
@package_version@ replacements. The procedure depends on
@@ -584,7 +848,7 @@
</section>
<section xml:id="standards.header.transition"><info><title>Transition Policy</title></info>
-
+
<variablelist>
<varlistentry>
<term>Existing Small Packages</term>
@@ -625,7 +889,7 @@
</section>
<section xml:id="standards.cvs"><info><title>Using CVS</title></info>
-
+
<simpara>
This section applies only to packages using CVS at cvs.php.net.
</simpara>
@@ -726,7 +990,7 @@
</section>
<section xml:id="standards.exampleurls"><info><title>Example URLs</title></info>
-
+
<para>
Use <literal>example.com</literal>, <literal>example.org</literal>
and <literal>example.net</literal> for all example URLs
@@ -735,9 +999,9 @@
</section>
<section xml:id="standards.naming"><info><title>Naming Conventions</title></info>
-
+
<section><info><title>Global Variables and Functions</title></info>
-
+
<para>
If your package needs to define global variables, their names
should start with a single underscore followed by the package
@@ -746,9 +1010,9 @@
</para>
<para>
Global functions should be named using the <quote>studly caps</quote>
- style (also referred to as <quote>bumpy case</quote> or <quote>camel
- caps</quote>). In addition, they should have the package name as
- a prefix, to avoid name collisions between packages. The initial letter
+ style (also referred to as <quote>bumpy case</quote> or <quote>camel
+ caps</quote>). In addition, they should have the package name as
+ a prefix, to avoid name collisions between packages. The initial letter
of the name (after the prefix) is lowercase, and each letter that
starts a new <quote>word</quote> is capitalized. An example:
<informaltable>
@@ -763,7 +1027,7 @@
</para>
</section>
<section><info><title>Classes</title></info>
-
+
<para>
Classes should be given descriptive names. Avoid using abbreviations
where possible. Class names should always begin with an uppercase
@@ -784,10 +1048,10 @@
</para>
</section>
<section><info><title>Class Variables and Methods</title></info>
-
+
<para>
- Class variables (a.k.a properties) and methods should
- be named using the <quote>studly caps</quote> style (also referred
+ Class variables (a.k.a properties) and methods should
+ be named using the <quote>studly caps</quote> style (also referred
to as <quote>bumpy case</quote> or <quote>camel caps</quote>).
Some examples (these would be <quote>public</quote> members):
<informaltable>
@@ -836,7 +1100,7 @@
</para>
</section>
<section><info><title>Constants</title></info>
-
+
<para>
Constants should always be all-uppercase, with underscores to
separate words. Prefix constant names with the uppercased name
@@ -863,7 +1127,7 @@
</section>
<section xml:id="standards.file"><info><title>File Formats</title></info>
-
+
<para>
All scripts contributed to PEAR must:
<itemizedlist>
@@ -874,7 +1138,9 @@
</listitem>
<listitem>
<para>
- Use ISO-8859-1 character encoding
+ Use ISO-8859-1 or UTF-8 character encoding. The encoding may be
+ declared using <literal>declare(encoding = 'utf-8');</literal> at the
+ top of the file.
</para>
</listitem>
<listitem>
@@ -908,7 +1174,7 @@
</section>
<section xml:id="standards.e_strict"><info><title><literal>E_STRICT</literal>-compatible code</title></info>
-
+
<para>
Starting on 01 January 2007, all new code that is suggested for
inclusion into PEAR must be
@@ -925,24 +1191,24 @@
</para>
<para>
More details on this part of the Coding Standards can be found in
- the corresponding <link linkend="rfc.estrict-compatibility">RFC</link>.
+ the <link linkend="rfc.estrict-compatibility">corresponding RFC</link>.
</para>
</section>
<section xml:id="standards.errors"><info><title>Error Handling Guidelines</title></info>
-
-
+
+
<para>
This part of the Coding Standards describes how errors are
handled in PEAR packages that are developed for PHP 5 and 6. It
uses Exceptions, introduced in PHP 5.0 with Zend Engine 2, as
the error handling mechanism.
</para>
-
+
<section><info><title>Definition of an error</title></info>
-
+
<para>
An error is defined as an unexpected, invalid program state from
@@ -952,7 +1218,7 @@
</para>
<example><info><title>One pretty straightforward example for an error</title></info>
-
+
<programlisting role="php">
<![CDATA[
/*
@@ -982,7 +1248,7 @@
</para>
<example><info><title>Error handling with recovery</title></info>
-
+
<programlisting role="php">
<![CDATA[
@@ -1034,7 +1300,7 @@
</para>
<example><info><title>Incomplete recovery</title></info>
-
+
<programlisting role="php">
<![CDATA[
@@ -1067,7 +1333,7 @@
</section>
<section><info><title>Error Signaling in PHP 5 PEAR packages</title></info>
-
+
<para>
Error conditions in PEAR packages written for PHP 5 must be
@@ -1127,7 +1393,7 @@
</para>
<example><info><title/></info>
-
+
<programlisting role="php">
<![CDATA[
function divide($x, $y)
@@ -1149,7 +1415,7 @@
</para>
<example><info><title/></info>
-
+
<programlisting role="php">
<![CDATA[
/*
@@ -1180,7 +1446,7 @@
</para>
<example><info><title>Rethrowing an exception</title></info>
-
+
<programlisting role="php">
<![CDATA[
@@ -1197,7 +1463,7 @@
</example>
<example><info><title>Letting exceptions bubble up</title></info>
-
+
<programlisting role="php">
<![CDATA[
@@ -1233,7 +1499,7 @@
</section>
<section><info><title>Exceptions and normal program flow</title></info>
-
+
<para>
Exceptions should never be used as normal program flow. If
@@ -1254,7 +1520,7 @@
</para>
<example><info><title/></info>
-
+
<programlisting role="php">
<![CDATA[
/**
@@ -1284,7 +1550,7 @@
</section>
<section><info><title>Exception class hierarchies</title></info>
-
+
<para>
All of PEAR packages exceptions must be descendant from
@@ -1302,7 +1568,7 @@
</section>
<section><info><title>Documenting Exceptions</title></info>
-
+
<para>
Because PHP, unlike Java, does not require you to explicitly
@@ -1315,7 +1581,7 @@
Exceptions should be documented using the
<literal>@throws</literal> phpdoc keyword
</title></info>
-
+
<programlisting role="php">
<![CDATA[
@@ -1341,7 +1607,7 @@
</para>
<example><info><title/></info>
-
+
<programlisting role="php">
<![CDATA[
/**
@@ -1363,7 +1629,7 @@
</para>
<example><info><title/></info>
-
+
<programlisting role="php">
<![CDATA[
/**
@@ -1377,7 +1643,7 @@
</section>
<section><info><title>Exceptions as part of the API</title></info>
-
+
<para>
Exceptions play a critical role in the API of your
@@ -1434,8 +1700,12 @@
</section>
</section>
- <section xml:id="standards.bestpractices"><info><title>Best practices</title></info>
-
+
+ <section xml:id="standards.bestpractices">
+ <info>
+ <title>Best practices</title>
+ </info>
+
<para>
There are other things not covered by PEAR Coding Standards which
are mostly subject of personal preference and not directly related
@@ -1446,10 +1716,111 @@
recommendation could be made to keep consistency within package
and respect personal style of other developers.
</para>
+
+
+ <section xml:id="standards.bestpractices.readability">
+ <title>Readability of code blocks</title>
+
+ <para>Related lines of code should be grouped into blocks, seperated
+ from each other to keep readability as high as possible. The definition
+ of "related" depends on the code :)</para>
+
+ <para>For example:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+if ($foo) {
+ $bar = 1;
+}
+if ($spam) {
+ $ham = 1;
+}
+if ($pinky) {
+ $brain = 1;
+}
+?>]]></programlisting>
+
+ <para>is a lot easier to read when seperated:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+if ($foo) {
+ $bar = 1;
+}
+
+if ($spam) {
+ $ham = 1;
+}
+
+if ($pinky) {
+ $brain = 1;
+}
+?>]]></programlisting>
+ </section>
+
+
+ <section xml:id="standards.bestpractices.returnearly">
+ <title>Return early</title>
+
+ <para>To keep readability in functions and methods, it is wise to return
+ early if simple conditions apply that can be checked at the beginning of
+ a method:</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+function foo($bar, $baz)
+{
+ if ($foo) {
+ //assume
+ //that
+ //here
+ //is
+ //the
+ //whole
+ //logic
+ //of
+ //this
+ //method
+ return $calculated_value;
+ } else {
+ return null;
+ }
+}
+?>]]></programlisting>
+
+ <para>It's better to return early, keeping indentation and brain power
+ needed to follow the code low.</para>
+
+ <programlisting role="php"><![CDATA[<?php
+
+function foo($bar, $baz)
+{
+ if (!$foo) {
+ return null;
+ }
+
+ //assume
+ //that
+ //here
+ //is
+ //the
+ //whole
+ //logic
+ //of
+ //this
+ //method
+ return $calculated_value;
+}
+?>]]></programlisting>
+ </section>
</section>
- <section xml:id="standards.sample"><info><title>Sample File (including Docblock Comment standards)</title></info>
-
+
+ <section xml:id="standards.sample">
+ <info>
+ <title>Sample File (including Docblock Comment standards)</title>
+ </info>
+
<para>
The source code of PEAR packages are read by thousands
of people. Also, it is likely other people will become
@@ -1729,8 +2100,12 @@
</para>
</section>
- <section xml:id="standards.toolbox"><info><title>The PEAR toolbox</title></info>
-
+
+ <section xml:id="standards.toolbox">
+ <info>
+ <title>The PEAR toolbox</title>
+ </info>
+
<para>
PEAR provides some tools to help developers keep their code clean
and free of coding standards related errors.