Please review our coding standards

From: Date: Sat, 28 Apr 2001 09:36:03 +0000
Subject: Please review our coding standards
Groups: php.general 
Request: Send a blank email to php-general+get-50741@lists.php.net to get a copy of this message
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 steven@haryan.to

« previous php.general (#50741) next »