source: trunk/docs/coding_standards.txt @ 214

Last change on this file since 214 was 214, checked in by quinn, 17 years ago

Q - Final check-in before releasing trunk as version 2.1

File size: 13.0 KB
Line 
1Strangecode coding standards
229 Aug 2005 20:12:49
3
4
5======================================================================
6Preamble
7======================================================================
8
9Our standards follow closely the PEAR coding standards.
10
11Essential reading:
12http://pear.php.net/manual/en/standards.php
13
14
15======================================================================
16File naming conventions
17======================================================================
18
19script.php              Public accessible scripts.
20
21Auth_SQL.inc.php        One PHP Class to be included. The filename is the
22                        type of class, underscore, name. Or if in subdirs,
23                        this could be /Auth/SQL.inc.php while the class name
24                        remains "Auth_SQL"
25
26some_file.inc.html      HTML file, which may or may not have some PHP,
27                        but will be included by some other PHP file. Never
28                        includes sensitive code as these files may be accessed
29                        directly in the web root.
30
31script.cli.php          A command-line executable script, possibly executed
32                        with CRON. Outputs TEXT if any instead of HTML.
33
34schema.mysql            Database schema file that goes with the application.
35
36main.screen.css         CSS file with media: screen/print/all
37main.print.css
38
39
40======================================================================
41Indenting and wrap
42======================================================================
43
44Use an indent of 4 spaces, with no tabs. Code and especially comments should
45be wrapped <= 80 characters. Exceptions are made in the case where code
46readability is significantly improved with longer lines.
47
48
49======================================================================
50Control Structures
51======================================================================
52
53These include if, for, while, switch, etc. Here is an example if statement,
54since it is the most complicated of them:
55
56    if ((condition1) || (condition2)) {
57        action1;
58    } else if ((condition3) && (condition4)) {
59        action2;
60    } else {
61        defaultaction;
62    }
63
64Control statements should have one space between the control keyword
65and opening parenthesis, to distinguish them from function calls.
66
67Even in the case of an if with no else clauses, and only a 1 line action,
68the curly braces should still be used:
69
70    if (condition) {
71        action;
72    }
73
74This improves readability and allows easy extension of the clause.
75
76For switch statements:
77
78    switch (condition) {
79    case 1:
80        action1;
81        break;
82
83    case 2:
84        action2;
85        break;
86
87    default:
88        defaultaction;
89        break;
90
91    }
92
93
94======================================================================
95Function Calls
96======================================================================
97
98Functions should be called with no spaces between the function name,
99the opening parenthesis, and the first parameter; spaces between commas
100and each parameter, and no space between the last parameter, the
101closing parenthesis, and the semicolon. Here's an example:
102
103    $var = foo($bar, $baz, $quux);
104
105As displayed above, there should be one space on either side of an
106equals sign used to assign the return value of a function to a
107variable. In the case of a block of related assignments, more space
108may be inserted to promote readability:
109
110    $short         = foo($bar);
111    $long_variable = foo($baz);
112
113
114======================================================================
115Function Definitions
116======================================================================
117
118Function declaractions follow the "one true brace" convention:
119
120    function fooFunction($arg1, $arg2 = '')
121    {
122        if (condition) {
123            statement;
124        }
125        return $val;
126    }
127
128Arguments with default values go at the end of the argument list. Always
129attempt to return a meaningful value from a function if one is appropriate.
130
131Recommend using studlyCaps for function names, to distinguish from php
132internal functions which standard on under_score_space() style names.
133
134
135======================================================================
136Return values
137======================================================================
138
139When functions return boolean values, use 'return false;' or 'return true;'
140as opposed to 'return 0;' or 'return 1;' or 'return(-1);'.
141
142
143======================================================================
144String concatenation
145======================================================================
146
147Always include a space before and after the concatenation operator '.' which
148improves readability and improves search-and-replace of adjacent elements.
149
150    $something = $blah . funky() . ".\".=" . $blab;
151
152is better than:
153
154    $something = $blah.funky().".\".=".$blab;
155
156
157======================================================================
158Quote marks
159======================================================================
160
161Use the single quote marks ' to enclose simple strings whenever possible.
162Double quote marks " require extra parsing and thus slow things down, but
163are necessary if entities there must be swapped-out such as variables or
164control characters.
165
166        $var['singlequote'] = 'singlequote';
167        $var["doublequote-$i"] = "$vars and \n funny \t %s things need doublequotes";
168        $var['doublequote-' . $i] = $var . 'you can do this' . "\t %s" . $var2 .
169        'but it isn\'t any better';
170
171
172======================================================================
173Printing html
174======================================================================
175
176For large or complex blocks of HTML, using the following method is much faster
177and safer than echo because the php processor is bypassed and content goes
178directly to output:
179
180    <?php
181    if (something) {
182        // Here comes the HTML...
183        ?>
184        <div class="sc-tiny">
185            <a href="<?php echo $app->ohref('/contact.php') ?>">Contact us</a>
186        </div>
187        <?php
188    } else if (somethingelse) {
189        ?><h1>Just a little html</h1><?php
190    }
191    ?>
192
193
194======================================================================
195Comments
196======================================================================
197
198Function comments should follow the Javadoc standard, with detailed
199function comments and one-line pointers along the way:
200http://java.sun.com/products/jdk/javadoc/writingdoccomments/index.html
201
202Here is an example of the codebase method Email::validEmail():
203
204    <?php
205    /**
206     * Validates an email address based on the recommendations in RFC 3696.
207     * Is more loose than restrictive, to allow the many valid variants of
208     * email addresses while catching the most common mistakes. Checks an array too.
209     * http://www.faqs.org/rfcs/rfc822.html
210     * http://www.faqs.org/rfcs/rfc2822.html
211     * http://www.faqs.org/rfcs/rfc3696.html
212     * http://www.faqs.org/rfcs/rfc1035.html
213     *
214     * @access  public
215     * @param   mixed  $email  Address to check, string or array.
216     * @return  bool    Validity of address.
217     * @author  Quinn Comendant <quinn@strangecode.com>
218     * @since   30 Nov 2005 22:00:50
219     */
220    function validEmail($email)
221    {
222        $app =& App::getInstance();
223   
224        // If an array, check values recursively.
225        if (is_array($email)) {
226            foreach ($email as $e) {
227                if (!$this->validEmail($e)) {
228                    return false;
229                }
230            }
231            return true;
232        } else {
233            // To be valid email address must match regex and fit within the lenth constraints.
234            if (preg_match($this->getParam('regex'), $email, $e_parts) && strlen($e_parts[2]) < 64 && strlen($e_parts[3]) < 255) {
235                return true;
236            } else {
237                $app->logMsg(sprintf('Invalid email: %s', $email), LOG_INFO, __FILE__, __LINE__);
238                return false;
239            }
240        }
241    }
242    ?>
243
244Single line comments should be of the double-slash variety, and be on the line above the
245code being commented upon:
246
247    <?php
248    // If the last word in $var is peanuts, set $need_peanuts to TRUE.
249    $need_peanuts = preg_match('/peanuts$/i', $var);
250    ?>
251
252
253======================================================================
254Including Code
255======================================================================
256
257If you are including a class, function library, or anything else which would
258cause a parse error if included twice, always use include_once. This will
259ensure that no matter how many factory methods we use or how much dynamic
260inclusion we do, the library will only be included once.
261
262If you are including a static filename, such as a conf file or a template
263that is _always_ used, use require.
264
265If you are dynamically including a filename, or want the code to only be
266used conditionally (an optional template), use include.
267
268
269======================================================================
270PHP Code Tags
271======================================================================
272
273ALWAYS use <?php ?> to delimit PHP code, not the <?php ?> shorthand. Even
274use <?php echo $name ?> instead of <?php echo $name; ?>.
275
276
277======================================================================
278php.ini settings
279======================================================================
280
281All code should work with register_globals = Off. This means using
282$_GET, $_POST, $_COOKIE, $_SESSION,
283$_SERVER, and $_ENV to access all get, post, cookie,
284session, server, and environment data, respectively.
285
286All code should work with error_reporting = E_ALL. Failure to do so would
287result in ugly output, error logs getting filled with lots of warning messages,
288or even downright broken scripts.
289
290All code should work regardless of the setting of magic_quotes_gpc.
291Form data should be passed through stripslashes if necessary.
292
293No code should assume that '.' is in the include path. Always
294specify './' in front of a filename when you are including a file in
295the same directory.
296
297
298======================================================================
299XHTML 1.0 Compliance
300======================================================================
301
302All HTML should be valid XHTML 1.0 verfied with the
303W3C Markup Validation Service: http://validator.w3.org/
304
305All tag names and parameters must be lower case including javascript
306event handlers:
307
308    <div class="mofogo">...</div>
309    <a href="http://www.example.com/" onmouseover="status=''" onmouseout="status=''">...</a>
310
311All tag parameters must be of a valid parameter="value" form (numeric
312values must also be surrounded by quotes).  For parameters that had no
313value in HTML, the parameter name is the value.  For example:
314
315    <input type="checkbox" checked="checked" />
316    <select name="example">
317        <option selected="selected" value="1">Example</option>
318    </select>
319    <td nowrap="nowrap">Example</td>
320
321All tags must be properly closed. Tags without a closing part must follow the
322XHTML convention and end with a space and a slash:
323
324    <br />
325    <hr />
326    <img src="example.gif" alt="Example" />
327    <input type="submit" value="Example" />
328
329All form definitions must be on their own line and either fully defined within
330a <td></td> pair or be outside table tags. Forms must also always have an action
331parameter:
332
333    <form method="post" action="http://example.com/example.cgi">
334    <table>
335        <tr><td>example</td></tr>
336    </table>
337    </from>
338
339    <table>
340        <tr><td>
341            <form action="javascript:void(0)" onsubmit="return false;">
342            </form>
343        </td></tr>
344    </table>
345
346All JavaScript tags must have a valid language and type parameters:
347
348    <script language="JavaScript" type="text/javascript">
349    <!--
350    ...
351    // -->
352    </script>
353
354Nothing may appear after </html>, therefore include any common footers after
355all other output.
356
357All images must have an alt parameter:
358
359    <img src="example.gif" alt="<?php echo _("Example"); ?>" />
360
361Input field of type "image" does not allow the border parameter, and may render
362with a border on some browsers.  Use the following instead:
363
364   <a href="" onclick="document.formname.submit(); return false;"><img src="example.gif" alt="<?php echo _("Example"); ?>" /></a>
365
366
367======================================================================
368Database Naming Conventions
369======================================================================
370
371All database tables need to make sure that their table and field names work in all
372databases. Many databases reserve words like 'uid', 'user', etc. for
373internal use, and forbid words that are SQL keywords (select, where,
374etc.). Adding '_tbl' to the end of the table name is a good idea for this reason
375and also improves searching for the table names in the code.
376
377A good way to do this for field names is to make the field name
378table_name_field_name.
379
380When building queries referencing two-or-more tables always preface columns
381with the table containing the column (admin_tbl.username, location_tbl.location_address).
382This method is much preferred over using aliases of table names (a.username, l.location_address).
383
384Table names should be singular (user_tbl instead of users_tbl).
Note: See TracBrowser for help on using the repository browser.