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