Dear folks,

I am composing a coding standards for our team. Bottom line, we are
using PEAR, object-oriented programming, extreme programming, and
PHPDoc. Below is the draft so far. I'd greatly appreciate it if
anybody care to give inputs on the document. Nevertheless, I hope
this could be useful to some.

Thank you.

Regards,
Steve


STYLE GUIDE FOR PHP DEVELOPERS
==============================

$Id$


0. General
----------

Understand these points and you are halfway there already.

0.1 We are writing PHP4 application here, not PHP3, nor Perl, Python, etc.
     So use PHP idioms.

0.2 We use the PEAR convention, except: 1) the tests in tests/ are written
     using unit test as much as possible. 2) preferred error reporting is
     slightly different. See 8.2 Reporting error.

0.3 Consistency matters.

0.4 Standards is important.

0.5 Readability matters. Especially since the code will be touched by
     several developers.


1. Formatting
-------------

1.0 Enclosing PHP code

     Always use <?php ?>.

1.1 Indentation

     Preferred indentation is using Tab (interpreted at 4 spaces).

1.2 Text width

     If possible, do not write long lines exceeding 79 columns. But this is
     not a strict requirement. In many cases it is much more convenient or
     vertically readable to put things in one line. So do that instead.

1.3 Curly brace placement

     This style:

       if (...) {
           ...
       }

     is more preferred than:

       if (...)
       {
           ...
       }

1.4 Whitespaces

     - No whitespace after function or method name. Example:

         exit()

       not

         exit ()

         $obj->method()

       not

         $obj->method ()

     - Generally, no whitespace inside the enclosing parenthesis, unless it
       enhances readability. Examples:

         ucfirst($str)

       not

         ucfirst( $str )

     - No whitespace between = in default argument definition.

         function f($a, $b=1, $c='')

       not

         function f($a, $b = 1, $c = '')

     - Add whitespace between assignment.

         $a = 1;

       not

         $a=1;

     - Whitespace in expressions are usually not necessary. But use them when
       they enhance readability.

         $a = $b + $c*(5*time());

1.5 Function names

     Function names are not case sensitive in PHP. Use the all-lowercase
     notation.

1.6 Quotes

     Use whichever ones you like. But if you can use '' for simple strings,
     and "" only if you need interpolation.

     Avoid backslashism! Use ' to quote ", use " to quote '. You can also
     utilize PHP4's here-documents.

       print <<<EOT;
       Some
       multiline
       text
       with
       "quotes"
       EOT

     However, here-document has one disadvantage: it messes indentation. So
     choose wisely.

1.7 Blank lines

     - Separate each class with two blank lines.

     - Separate each function and variable definition in the class with one
       blank line.

     - Give one blank line after the class definition.

       Example:

         class MyClass {

             function myMethod() {
                 ...
             }

             var $myAttr1;

             var $myAttr2;
         }


         class YourClass {
         }


2. Internationalization
-----------------------

gettext().


3. Comments
-----------

2.1 Inline comments.

     Inline comments are used to explain a particular small part of a code.
     Example:

       $var = 2;
       $Good or $var--;   // compensate for bad weather

     Use inline comments sparingly. Code should already be clear anyway.

2.2 Debugging comments.

     # is used to comment out certain parts of a code during debugging.

2.3 Documentation comments.

     These use the JavaDoc/PHPDoc syntax. Give to each class, class variable,
     method, global constant, and function. Refer to their own documentation.
     One place to start: http://java.sun.com/j2se/javadoc/

     Below is the summary of the syntax.

     /**
      * Short description.
      *
      * @param   type   $name - description
      * @return  type           description
      *
      * Longer description .... .... .... .... .... .... .... ....
      * .... .... .... .... .... .... .... .... .... .... .... ....
      */
     function foo() {

     /**
      * Short description.
      */
     var $foo = '';

     /**
      * Short description.
      *
      * @var object ClassName
      */
     var $bar;

     /** Short description.
      *
      * Longer description...
      */
     define('CONSTANT_NAME', 1);

     No blank lines before the definition. A blank comment line between short
     description - long description - @param/@return.


3. Naming
---------

3.1 Classes

       ClassName

     Follow PEAR-style namespace "embedding". For example:

       Html_Parser
       Data_Item
       Data_Collection

3.2 Class attributes

       attributeName
       _internalAttributeName
       attributeNameThatClashesWithBuiltin_ (for example, empty_)

3.3 Methods

       methodName
       _internalMethodName
       methodNameThatClashesWithBuiltin_ (for example, empty_)

3.4 Variables

       variable_name
       Global_variable_name

     this is also acceptable:

       variableName
       GlobalVariableName

3.4 Constants

       CONSTANT_NAME

     PEAR-style package prefix:

       DB_CONSTANT_NAME
       DATA_COLLECTION_CONSTANT_NAME

3.5 Functions

       function_name


4. File organization
--------------------

4.1 All library codes will live in the PEAR root directory.

4.2 All PHP libraries and include files, is named with '.php' extension (ie.
     no '.lib', '.inc', etc.). Test scripts is named with '.phpt' extension.

4.3 Always try to use register_once() to include libraries. If that is not
     possible, use include_once(). Example:

       require_once "Data/Collection.php";

4.4 All project- or product-specific library files should live under their
     own directory under the PEAR root.

     Example:

       /this/is/the/pear/root/
         Data/
           Collection.php
         DB/
         MyProjName/
           MyClass.php

4.5 For now, write one class per file (because of current PHPDoc's
     limitation).


5. Testing
----------

5.1 Follow the Extreme Programming methodology.

5.2 Create test scripts and put them in tests/ subdirectory. Use phpunit for
     the testing framework.

5.3 How to make test script:

     - a test script tests one or more classes;

     - name the script file after the [main] class you are testing. Give it
       extension .phpt (to avoid PHPDoc parsing the file). For example, if
       you want to test Template_Processor, create Template_Processor.phpt in
       the Template/tests/ directory.

     - require the phpunit file at the very top, to enable maximum warning
       level.

     - create one or more test case classes. For example,
       Template_Processor_TestCase.

     - create one function that will return the test suite class (name this
       function with the _makeSuite suffix). For example,
       Template_Processor_makeSuite. Add all the test case(s) and return the
       resulting test case.

     - create one test runner class. For example,
       Template_Processor_TextRunner.

     - instantiate the test runner class. For example, create the object
       $Template_Processor_TestRunner. Run the test runner.

     See Template_Processor.phpt in the lib/common/Template/tests/ directory
     for an example implementation of this.


6. Creating documentation
-------------------------

6.1 For API documentation, use Javadoc syntax. Generate the documentation
     using PHPDoc (included with PEAR). See one of the class files to see an
     example of this. Refer to the Javadoc manual for more details. A few
     tips on writing doc comments:

     - Always use:

       /**
        * One sentence documentation.
        */

       Instead of:

       /** One sentence documentation. */

       PHPDoc gets a little confused with the later.

     - The short description is a short sentence, in an imperative tone,
       ended with a period.

     - If the longer description is composed of more than one paragraphs, use
       <p>.

6.2 For other developer documentation (README files, Changelog, etc), use
     plain text files (such as this guide).

6.3 For application user documentation, use whatever format you like. Stick
     to simple, common, portable format like HTML and PDF.


7. Database programming
-----------------------

Perhaps we will use the database abstraction classes from PEAR in the
future. Currently we only use MySQL, so mysql_* will do. End users will
seldom touch this, however, since we are providing higher level abstraction
classes (for example, through Data_Collection classes).


8. Error handling
-----------------

8.1 Return values

     Do always check return values of functions, especially those that
     access/manipulate external resources like database (mysql_*), file I/O,
     remote URLs, shared memory, etc. Suppress error output of the function
     with @ if necessary. For example:

       $res = @mysql_query(...);
       if (!$res) {
           # deal with error...
       }

8.2 Reporting error

     If you write your own function or method, I recommend a variation of the
     PEAR style. The PEAR style is directly returning a PEAR_Error whenever a
     function encountered an error condition. I find it rather cumbersome,
     since the error checking becomes verbose:

       function yourMethod($foo) {
           if ($bar) {
               # an error condition...
               return new PEAR_Error($msg);
           }
       }

       $result = $obj->yourMethod($foo);
       if (PEAR::isError($result)) {      // cumbersome!
           # react accordingly
       }

     The common idiom is like this:

       if (!$obj->yourMethod($foo)) ...   // if fails, ...
       if ($obj->yourMethod($foo)) ...    // if success, ...

     Every PHP programmer is familiar to this idiom. It is simple, and
     simplicity matters because we will do a bunch of these.

     So what we do is store the PEAR_Error object in the object attribute
     (recommended name is $error). And we can also use raiseError() directly
     if you think the error should potentially stop execution if needed (if
     you want to use this style, your class must be a descendant of PEAR).

       function yourMethod($foo) {
           if ($bar) {
               # an error condition...
               $this->error = $this->raiseError($msg);
               return;   // return false
           }
           return 1;   // return success
       }

       if ($obj->yourMethod($foo)) {
           # react accordingly. PEAR_Error is available in $obj->error;
       }

     This is like the C errno() style but specific per object. Multithreading
     is not relevant in the current PHP program so this is not a problem.

     In classes that do not subclass PEAR, or in normal functions, you can
     use the 'new PEAR_Error()' style.

     Let's hope that PHP will soon support exceptions, so handling errors
     will become easier.


9. Portability
--------------

9.1 Always use <?php ?>.

9.2 Try to make your library code work with or without register_globals
     turned on. Better still, do not use globals at all in the library code.

9.3 magic quotes. This one is a pain to work with portably, since we do not
     know whether an argument comes from an external source, or from
     GET/POST/Cookie parameter, or neither. Therefore, all library codes
     should probably assume magic_quotes_gpc is off, so it does not bother
     with stripslashing.


10. References
--------------

- PHP coding standards

- PEAR documentation

- PEAR coding standards

- phpunit documentation


12. Comments, suggestions?
--------------------------

If you do not understand some part, have objection to a certain rule, or
have an idea to improving style, please discuss it with me.


Apr 19, 2001
Steven Haryanto
[EMAIL PROTECTED]


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to