Coding Rules

From ClaroDevel

This document synthesizes the coding rules the core Claroline has decided to follow now. These coding rules has been build on a draft document written by Hugues Peeters, discussed and validated on a meeting in June 2004 by Christophe Gesché, Guillaume Lederer, Sébastien Piraux, Mathieu Laurent, and Aurélien Vanhamme.

Table of contents

Coding Rules

Language

We write all our code in English.

PHP Tags

We always use

<?php ?>

rather than

<? ?>

And we use also

<?php echo $myVar ?>

rather than

<?= $myVar ?>

Why ?

  • Compatibility with xml files (xhtml, rss, ...) where <?xml is used
  • Compatibility with 100% of php server where "short_open_tags" is off
  • "short_open_tags on" will be deprecated in PHP 6

Advice

  • Set "short_open_tags off" in your php.ini

White spaces

We add a blank line between lines of code. It creates paragraphs of code and helps to visualize it. You don't want to read books that have a thousand pages filled with line after line and no breaks; nobody wants to read code like that either.

Also, using spaces around operators and after comma's can help to make the code more readable. function something (param a, paramb)

if ( (a && c) ||  (a == b + c) && !b && trim( strip_tags($string) ) );

Indentation

We now use white spaces instead of tabs for indentation. Our indentation step equals 4 white spaces.

PHP example:

if ( $cmd == 'exUpload' )
{
    if ( ! isset( $_FILES['userFile'] ) )
    {
        $dialogBox .= 'Error. No file uploaded';
    }
}

THERE IS ONE AND ONLY ONE INDENTATION IN A FILE. We don't mix anymore indentation according we're in a HTML, an SQL or a PHP part. PHP is always our leading indentation.

It is still possible to enhance SQL and HTML structure by using new lines.

SQL example :

SELECT `temps` AS publicationDate,
        CONCAT(`title`,' ',`contenu`) AS content
FROM `mytable`
WHERE CONCAT(title,contenu) != 'blabla'
ORDER BY temps DESC
LIMIT 50;

HTML example :

<table>
<tr>
<td>
<p>Hello world</p>
</td>
<td>
<p>Claroline rules</p>
</td>
<tr>
</table>

Note: Concerning HTML, for those who really don't feel comfortable with no indentation at all in HTML, the use of a "one space" indentation is tolerated. But this can not thwart the leading PHP indentation.

Alignment

We try to align the most as I can, as it reaaaaly make the reading easier.

example :

$_user ['firstName'] = $uData ['prenom'    ];
$_user ['lastName' ] = $uData ['nom'       ];
$_user ['mail'     ] = $uData ['email'     ];
$_user ['lastLogin'] = $uData ['login_date'];

Brackets

We use this notation

if ($wwwww > $jjjjj)
{
....(write code here)
}

instead of this one

if ($wwwww > $jjjjj) {
....(write code here)
}

or this one

if ($wwwww > $jjjjj)
    {
    ...(write code here)
    }

If statement can hold on a single line, we write it without bracket. But if we have to pass to a new line, we automatically insert the bracket.

if ($myVariable) echo 'hello world'; --> OK
if ($myVariable)
    echo 'hello world';          --> NOT OK

What about complex 'if statement' unable to holding on a single line ?

We're using using this notation :

if (   (   ( trim ($myFirstVar) && $mySecondVar)
         ||  do_a-complex_check($myThirdvar)        )
    && (     do_another_complex_check($myFourthVar) ) )

How do we code PHP output

echo 'bala abala' . $maFirstVar . ' blabla' . "\n"
    . 'bbla bla bla blka bla blka' . "\n"
    . 'blabla' . $myVarList['key'] . "\n" ;
  1. Single quote are used, and double quote is used for "\n", "\t", ...
  2. We try to never insert PHP $variable into the string.
  3. We frequently use the new line character ("\n") to structure the output, as it makes easier the source code reading from a web browser
  4. We try to use the most as we can the claro_disp... function family available into the claro_main.lib.php, as it increases the display consistence. claro_html class come to complete this collection.
  5. if the string is output on many line the dot for concat is starting the line with a tabulation before

How do we code SQL statement

$sql = "SELECT item1, 
               item2 AS alias2, 
               myTbl.item3 AS item3
        FROM `myTable` AS myTbl
        WHERE condition1 = '" . addslashes($phpCondition1) . "'
          AND condition2 = '" . addslashes($phpCondition2) . "'
           OR condition3 = '" . addslashes($phpCondition3) . "'";

claro_sql_query($sql);
  1. statement are in double quote.
  2. strings in statement are in simple quote
  3. We always write the SQL query in a variable before submitting it to the database. It allows us to display queries more easily in debugging phase. Some of us always use '$sql' as the variable. It allows them to keep it short and to not leave too much space for the query. They manage to prevent any conflict with other possible $sql.
  4. the 'addslashes()' function is used inside the query (not before).
  5. All the SQL keywords are written in uppercase. The main SQL keywords are aligned on the left side, the subordinate keyword (like AND, OR) are aligned on the right part of the related SQL keyword.
  6. We use the Claroline mySQL API available on the 'claro_main.lib.php' library file. This layer allows us to handle gracefully SQL connection, error handling and so on. Moreover it will considerably facilitate any possible database shift in the future.
  7. We use AS when aliasing
  8. We use BY when order
  9. We ban * usage
  10. alias follows naming rules of variables
- claro_sql_query($sql)                  : basic sql query wrapper
- claro_sql_field_names($sql)            : get the name of the specified fields in 
                                           a query result
- claro_sql_query_fetch_all($sql)        : returns all the result row in
                                           associative array
- claro_sql_query_fetch_all_cols($sql)   : returns all the result in
                                           associative array ARRANGED BY
                                           COLUMNS.
- claro_sql_query_get_single_value($sql) : returns only a single
                                           result value
- claro_sql_query_get_single_row($sql)   : returns only the first row of the result
- claro_sql_query_affected_rows($sql)    : returns the number of rows
                                           affected by the query
- claro_sql_query_insert_id($sql)        : returns the last id generated by
                                           the last inserted row

Variables name

We name variables in studlyCaps

$myVariable
$prefix_myVariable

We try to name the variables in singular mode rather than plural, whatever the context. Because plural form is a common source of misspelling error. If we need to express plurality inside the variable name, using term like 'list' or 'count' can help.

example : $users becomes $userList;

NOTE: Problem with the term 'number' (ambiguity). $studentNumber. Does it mean the total number of students or the number of this student ? To prevent that ambiguity, we use 'count' instead of 'number'. (borrowed from Steve Mc Connel)

Constants

We write constants in UPPERCASE, and if MULTIPLE_WORDS_LIKE_THIS.

Function name

we use under_scores to separate words, instead of studlyCaps.

What about fields and table names in database ?

  • We write all the tables and column names in English
  • Primary keys of a table are called 'id'
  • Foreign key of a table are called following this rule : 'foreigntable_id'
  • The field name is in small letters, if you must use some words, the first letter of the second (third,...) word must be a capital letter. (like a variable name)
  • We don't use magic value anymore, but ENUM column (if a set is needed, a foreign table would be needed probably soon)
  • We begin the name of table with same prefix (like label of tools) for all table of a same tool
  • If the only purpose of table is a relation table, we introduce a second prefix '_rel_' just after the first one

Arrays

We always quote the ARRAY the key with single quote. It's faster and more readable than double quote. It's better than no quote at all, because PHP will first try to see if it isn't a constant before valuating it as a string key. And above all, since PHP5 it has became mandatory to quoter array key.

$myVarList['key']

Comments

1. We never use Perl like comments (#). As we try to keep them for possible future precompilation commands or something like that.

2. We try to use mostly C like comment (/* */), ABOVE the concerned instructions

/*
 * This is my comment for the PHP instructions below.
 * This is my comment for the PHP instructions below.
 */

PHP statements

- We Use the C++ like comment (//) for very short comments. These comments should be above the concerned code, if at all possible.


We structure code section according to the conventions below

/*> > > > > > > > > > > >  BIG SECTION CHANGE < < < < < < < < < < < <*/

/*=====================================================================
                                   LEVEL 1
  =====================================================================*/

/*----------------------------------------------------------------------
                                  LEVEL 2
  ----------------------------------------------------------------------*/

For the class and function interfaces, we use the conventions from the Java documentation, so I can retrieve these comments later to build complete documentation with PHP Documentor (http://pear.php.net/package/PhpDocumentor, from the Pear collection of reusable PHP components).

NOTE. As PHP is a typeless language. So we introduce the type of our parameters and return variable int the javadoc line.

Details of the Java Documentation convention can be found at :

How to Write Doc Comments for the Javadoc Tool
http://java.sun.com/j2se/javadoc/writingdoccomments/index.html

A JavaDoc comment example:

/**
* Draws as much of the specified image as is currently available
* with its northwest corner at the specified coordinate (x, y).
* This method will return immediately in all cases, even if the
* entire image has not yet been scaled, dithered and converted
* for the current output device.
*
* If the current output representation is not yet complete then
* the method will return false and the indicated {@link ImageObserver}
* object will be notified as the conversion process progresses.
*
* @author Sami Shaio
* @author Arthur van Hoff
*
* @param      string - $img the image to be drawn
* @param      int    - $x the x-coordinate of the northwest corner of the
*             destination rectangle in pixels
* @param      int - $y the y-coordinate of the northwest corner of the
*             destination rectangle in pixels
* @param      string - $observer the image observer to be notified as more of the
*             image is converted. May be null
* @return     boolean true if the image is completely loaded and was
*             painted successfully; false otherwise.
* @see        Image
* @see        ImageObserver
* @see        imageWrite
* @since      JDK1.0
* @deprecated imageWrite performs it faster
*/


function draw_image($img, $x, $y, $observer);

File and directory names

1. All files containing PHP code have to be suffixed with '.php' extension. This is absolutely necessary for security reason.

2. We try to keep directory names very short ('inc', 'lang', 'conf', etc.), like in UNIX. That way the Claroline structure spread gracefully into the UNIX directory tree. we're less strict for file name.

3. We specify in the file name when a file have to be included into other ones. Moreover, we had a second suffix dedicated to file which have to be included into other ones.

  • 'myfile.lib.php' file containing library code (functions or classes)
  • 'myfile.conf.php' file containing configuration code (like variable flags and constants)
  • 'myfile.lang.php' file containing translation work 'myfile.inc.php' file which are included into parent files but are not from the three previous family

NOTE:

We don't use anymore the '.class' suffix. We rather use the
'.lib' suffix for that purpose (as it doesn't matter that the file
content is classes or functions, actually it's often a mixed
of both).

We don't reproduce anymore all the directory structure in the file name (like in Java)

myfile.inc.lib.php

It's too heavy, and if we need to change the place of the libraries we're stucked...

4. IMPORTANT NOTE. The core Claroline development team has not reached a settlement concerning file name composed of several names. For the moment the Claroline file structure allows three kinds of file naming types.

'external_module', 'externalModule', 'externalmodule' ?

It should be necessary to reach soon an agreement on this point.

Links

PHP.net

Phpdoc

Coding rules