blob: 925954c039e5c0a5baac1abdd24afbff2dfb6ea4 [file] [log] [blame]
Derek Jones619b1222011-10-10 16:26:27 -05001###############
2PHP Style Guide
3###############
4
Derek Jones8ede1a22011-10-05 13:34:52 -05005
6The following page describes the use of coding rules adhered to when
7developing CodeIgniter.
8
9.. contents:: Table of Contents
10
11File Format
12===========
13
14Files should be saved with Unicode (UTF-8) encoding. The BOM should
15*not* be used. Unlike UTF-16 and UTF-32, there's no byte order to
16indicate in a UTF-8 encoded file, and the BOM can have a negative side
17effect in PHP of sending output, preventing the application from being
18able to set its own headers. Unix line endings should be used (LF).
19
20Here is how to apply these settings in some of the more common text
21editors. Instructions for your text editor may vary; check your text
22editor's documentation.
23
24TextMate
25''''''''
26
27#. Open the Application Preferences
28#. Click Advanced, and then the "Saving" tab
29#. In "File Encoding", select "UTF-8 (recommended)"
30#. In "Line Endings", select "LF (recommended)"
31#. *Optional:* Check "Use for existing files as well" if you wish to
32 modify the line endings of files you open to your new preference.
33
34BBEdit
35''''''
36
37#. Open the Application Preferences
38#. Select "Text Encodings" on the left.
39#. In "Default text encoding for new documents", select "Unicode (UTF-8,
40 no BOM)"
41#. *Optional:* In "If file's encoding can't be guessed, use", select
42 "Unicode (UTF-8, no BOM)"
43#. Select "Text Files" on the left.
44#. In "Default line breaks", select "Mac OS X and Unix (LF)"
45
46PHP Closing Tag
47===============
48
49The PHP closing tag on a PHP document **?>** is optional to the PHP
50parser. However, if used, any whitespace following the closing tag,
51whether introduced by the developer, user, or an FTP application, can
52cause unwanted output, PHP errors, or if the latter are suppressed,
53blank pages. For this reason, all PHP files should **OMIT** the closing
54PHP tag, and instead use a comment block to mark the end of file and
55it's location relative to the application root. This allows you to still
56identify a file as being complete and not truncated.
57
Derek Jones129c1812011-10-05 17:15:44 -050058**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -050059
Derek Jones129c1812011-10-05 17:15:44 -050060 <?php
61
62 echo "Here's my code!";
63
64 ?>
65
66**CORRECT**::
67
68 <?php
69
70 echo "Here's my code!";
71
72 /* End of file myfile.php */
73 /* Location: ./system/modules/mymodule/myfile.php */
Derek Jones8ede1a22011-10-05 13:34:52 -050074
75Class and Method Naming
76=======================
77
78Class names should always start with an uppercase letter. Multiple words
79should be separated with an underscore, and not CamelCased. All other
80class methods should be entirely lowercased and named to clearly
81indicate their function, preferably including a verb. Try to avoid
82overly long and verbose names.
83
Derek Jones129c1812011-10-05 17:15:44 -050084**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -050085
Derek Jones129c1812011-10-05 17:15:44 -050086 class superclass
87 class SuperClass
88
89**CORRECT**::
90
91 class Super_class
Derek Jones8ede1a22011-10-05 13:34:52 -050092
93::
94
Derek Jones129c1812011-10-05 17:15:44 -050095 class Super_class {
Derek Jones8ede1a22011-10-05 13:34:52 -050096
Andrey Andreevd8e1ac72012-03-26 22:22:37 +030097 public function __construct()
Derek Jones129c1812011-10-05 17:15:44 -050098 {
Derek Jones8ede1a22011-10-05 13:34:52 -050099
Derek Jones129c1812011-10-05 17:15:44 -0500100 }
101 }
102
103Examples of improper and proper method naming:
104
105**INCORRECT**::
106
107 function fileproperties() // not descriptive and needs underscore separator
108 function fileProperties() // not descriptive and uses CamelCase
109 function getfileproperties() // Better! But still missing underscore separator
110 function getFileProperties() // uses CamelCase
111 function get_the_file_properties_from_the_file() // wordy
112
113**CORRECT**::
114
115 function get_file_properties() // descriptive, underscore separator, and all lowercase letters
Derek Jones8ede1a22011-10-05 13:34:52 -0500116
117Variable Names
118==============
119
120The guidelines for variable naming is very similar to that used for
121class methods. Namely, variables should contain only lowercase letters,
122use underscore separators, and be reasonably named to indicate their
123purpose and contents. Very short, non-word variables should only be used
124as iterators in for() loops.
125
Derek Jones129c1812011-10-05 17:15:44 -0500126**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500127
Derek Jones129c1812011-10-05 17:15:44 -0500128 $j = 'foo'; // single letter variables should only be used in for() loops
129 $Str // contains uppercase letters
130 $bufferedText // uses CamelCasing, and could be shortened without losing semantic meaning
131 $groupid // multiple words, needs underscore separator
132 $name_of_last_city_used // too long
133
134**CORRECT**::
135
136 for ($j = 0; $j < 10; $j++)
137 $str
138 $buffer
139 $group_id
140 $last_city
Derek Jones8ede1a22011-10-05 13:34:52 -0500141
142Commenting
143==========
144
145In general, code should be commented prolifically. It not only helps
146describe the flow and intent of the code for less experienced
147programmers, but can prove invaluable when returning to your own code
148months down the line. There is not a required format for comments, but
149the following are recommended.
150
151`DocBlock <http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#basics.docblock>`_
Timothy Warrenbb8ae012012-04-20 10:31:51 -0400152style comments preceding class, method, and property declarations so they can be
Derek Jones8ede1a22011-10-05 13:34:52 -0500153picked up by IDEs::
154
Derek Jones129c1812011-10-05 17:15:44 -0500155 /**
156 * Super Class
157 *
158 * @package Package Name
159 * @subpackage Subpackage
160 * @category Category
161 * @author Author Name
162 * @link http://example.com
163 */
164 class Super_class {
Derek Jones8ede1a22011-10-05 13:34:52 -0500165
166::
167
Derek Jones129c1812011-10-05 17:15:44 -0500168 /**
169 * Encodes string for use in XML
170 *
Derek Jones129c1812011-10-05 17:15:44 -0500171 * @param string
172 * @return string
173 */
174 function xml_encode($str)
Timothy Warrenbb8ae012012-04-20 10:31:51 -0400175
176::
177
178 /**
179 * Data for class manipulation
180 *
181 * @var array
182 */
183 public $data
184
185
Derek Jones8ede1a22011-10-05 13:34:52 -0500186
187Use single line comments within code, leaving a blank line between large
188comment blocks and code.
189
190::
191
Derek Jones129c1812011-10-05 17:15:44 -0500192 // break up the string by newlines
193 $parts = explode("\n", $str);
194
195 // A longer comment that needs to give greater detail on what is
196 // occurring and why can use multiple single-line comments. Try to
197 // keep the width reasonable, around 70 characters is the easiest to
198 // read. Don't hesitate to link to permanent external resources
199 // that may provide greater detail:
200 //
201 // http://example.com/information_about_something/in_particular/
202
203 $parts = $this->foo($parts);
Derek Jones8ede1a22011-10-05 13:34:52 -0500204
205Constants
206=========
207
208Constants follow the same guidelines as do variables, except constants
209should always be fully uppercase. *Always use CodeIgniter constants when
210appropriate, i.e. SLASH, LD, RD, PATH_CACHE, etc.*
211
Derek Jones129c1812011-10-05 17:15:44 -0500212**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500213
Derek Jones129c1812011-10-05 17:15:44 -0500214 myConstant // missing underscore separator and not fully uppercase
215 N // no single-letter constants
216 S_C_VER // not descriptive
217 $str = str_replace('{foo}', 'bar', $str); // should use LD and RD constants
218
219**CORRECT**::
220
221 MY_CONSTANT
222 NEWLINE
223 SUPER_CLASS_VERSION
224 $str = str_replace(LD.'foo'.RD, 'bar', $str);
Derek Jones8ede1a22011-10-05 13:34:52 -0500225
226TRUE, FALSE, and NULL
227=====================
228
229**TRUE**, **FALSE**, and **NULL** keywords should always be fully
230uppercase.
231
Derek Jones129c1812011-10-05 17:15:44 -0500232**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500233
Derek Jones129c1812011-10-05 17:15:44 -0500234 if ($foo == true)
235 $bar = false;
236 function foo($bar = null)
237
238**CORRECT**::
239
240 if ($foo == TRUE)
241 $bar = FALSE;
242 function foo($bar = NULL)
Derek Jones8ede1a22011-10-05 13:34:52 -0500243
244Logical Operators
245=================
246
247Use of **\|\|** is discouraged as its clarity on some output devices is
248low (looking like the number 11 for instance). **&&** is preferred over
249**AND** but either are acceptable, and a space should always precede and
250follow **!**.
251
Derek Jones129c1812011-10-05 17:15:44 -0500252**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500253
Derek Jones129c1812011-10-05 17:15:44 -0500254 if ($foo || $bar)
255 if ($foo AND $bar) // okay but not recommended for common syntax highlighting applications
256 if (!$foo)
257 if (! is_array($foo))
258
259**CORRECT**::
260
261 if ($foo OR $bar)
262 if ($foo && $bar) // recommended
263 if ( ! $foo)
264 if ( ! is_array($foo))
265
Derek Jones8ede1a22011-10-05 13:34:52 -0500266
267Comparing Return Values and Typecasting
268=======================================
269
270Some PHP functions return FALSE on failure, but may also have a valid
271return value of "" or 0, which would evaluate to FALSE in loose
272comparisons. Be explicit by comparing the variable type when using these
273return values in conditionals to ensure the return value is indeed what
274you expect, and not a value that has an equivalent loose-type
275evaluation.
276
277Use the same stringency in returning and checking your own variables.
278Use **===** and **!==** as necessary.
Derek Jones8ede1a22011-10-05 13:34:52 -0500279
Derek Jones129c1812011-10-05 17:15:44 -0500280**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500281
Derek Jones129c1812011-10-05 17:15:44 -0500282 // If 'foo' is at the beginning of the string, strpos will return a 0,
283 // resulting in this conditional evaluating as TRUE
284 if (strpos($str, 'foo') == FALSE)
Derek Jones8ede1a22011-10-05 13:34:52 -0500285
Derek Jones129c1812011-10-05 17:15:44 -0500286**CORRECT**::
287
288 if (strpos($str, 'foo') === FALSE)
289
290**INCORRECT**::
291
292 function build_string($str = "")
293 {
294 if ($str == "") // uh-oh! What if FALSE or the integer 0 is passed as an argument?
295 {
296
297 }
298 }
299
300**CORRECT**::
301
302 function build_string($str = "")
303 {
304 if ($str === "")
305 {
306
307 }
308 }
Derek Jones8ede1a22011-10-05 13:34:52 -0500309
310
311See also information regarding
312`typecasting <http://us3.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting>`_,
313which can be quite useful. Typecasting has a slightly different effect
314which may be desirable. When casting a variable as a string, for
315instance, NULL and boolean FALSE variables become empty strings, 0 (and
316other numbers) become strings of digits, and boolean TRUE becomes "1"::
317
318 $str = (string) $str; // cast $str as a string
319
320Debugging Code
321==============
322
323No debugging code can be left in place for submitted add-ons unless it
324is commented out, i.e. no var_dump(), print_r(), die(), and exit()
325calls that were used while creating the add-on, unless they are
326commented out.
327
328::
329
330 // print_r($foo);
331
332Whitespace in Files
333===================
334
335No whitespace can precede the opening PHP tag or follow the closing PHP
336tag. Output is buffered, so whitespace in your files can cause output to
337begin before CodeIgniter outputs its content, leading to errors and an
338inability for CodeIgniter to send proper headers. In the examples below,
339select the text with your mouse to reveal the incorrect whitespace.
340
Derek Jones8ede1a22011-10-05 13:34:52 -0500341
342Compatibility
343=============
344
345Unless specifically mentioned in your add-on's documentation, all code
346must be compatible with PHP version 5.1+. Additionally, do not use PHP
347functions that require non-default libraries to be installed unless your
348code contains an alternative method when the function is not available,
349or you implicitly document that your add-on requires said PHP libraries.
350
351Class and File Names using Common Words
352=======================================
353
354When your class or filename is a common word, or might quite likely be
355identically named in another PHP script, provide a unique prefix to help
356prevent collision. Always realize that your end users may be running
357other add-ons or third party PHP scripts. Choose a prefix that is unique
358to your identity as a developer or company.
359
Derek Jones129c1812011-10-05 17:15:44 -0500360**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500361
Derek Jones129c1812011-10-05 17:15:44 -0500362 class Email pi.email.php
363 class Xml ext.xml.php
364 class Import mod.import.php
365
366**CORRECT**::
367
368 class Pre_email pi.pre_email.php
369 class Pre_xml ext.pre_xml.php
370 class Pre_import mod.pre_import.php
Derek Jones8ede1a22011-10-05 13:34:52 -0500371
372Database Table Names
373====================
374
375Any tables that your add-on might use must use the 'exp\_' prefix,
376followed by a prefix uniquely identifying you as the developer or
377company, and then a short descriptive table name. You do not need to be
378concerned about the database prefix being used on the user's
379installation, as CodeIgniter's database class will automatically convert
380'exp\_' to what is actually being used.
381
Derek Jones129c1812011-10-05 17:15:44 -0500382**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500383
Derek Jones129c1812011-10-05 17:15:44 -0500384 email_addresses // missing both prefixes
385 pre_email_addresses // missing exp_ prefix
386 exp_email_addresses // missing unique prefix
Derek Jones8ede1a22011-10-05 13:34:52 -0500387
Derek Jones129c1812011-10-05 17:15:44 -0500388**CORRECT**::
389
390 exp_pre_email_addresses
391
392.. note:: Be mindful that MySQL has a limit of 64 characters for table
393 names. This should not be an issue as table names that would exceed this
394 would likely have unreasonable names. For instance, the following table
395 name exceeds this limitation by one character. Silly, no?
396 **exp_pre_email_addresses_of_registered_users_in_seattle_washington**
397
Derek Jones8ede1a22011-10-05 13:34:52 -0500398One File per Class
399==================
400
401Use separate files for each class your add-on uses, unless the classes
402are *closely related*. An example of CodeIgniter files that contains
403multiple classes is the Database class file, which contains both the DB
404class and the DB_Cache class, and the Magpie plugin, which contains
405both the Magpie and Snoopy classes.
406
407Whitespace
408==========
409
410Use tabs for whitespace in your code, not spaces. This may seem like a
411small thing, but using tabs instead of whitespace allows the developer
412looking at your code to have indentation at levels that they prefer and
413customize in whatever application they use. And as a side benefit, it
414results in (slightly) more compact files, storing one tab character
415versus, say, four space characters.
416
417Line Breaks
418===========
419
420Files must be saved with Unix line breaks. This is more of an issue for
421developers who work in Windows, but in any case ensure that your text
422editor is setup to save files with Unix line breaks.
423
424Code Indenting
425==============
426
427Use Allman style indenting. With the exception of Class declarations,
428braces are always placed on a line by themselves, and indented at the
429same level as the control statement that "owns" them.
430
Derek Jones129c1812011-10-05 17:15:44 -0500431**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500432
Derek Jones129c1812011-10-05 17:15:44 -0500433 function foo($bar) {
434 // ...
435 }
436
437 foreach ($arr as $key => $val) {
438 // ...
439 }
440
441 if ($foo == $bar) {
442 // ...
443 } else {
444 // ...
445 }
446
447 for ($i = 0; $i < 10; $i++)
448 {
449 for ($j = 0; $j < 10; $j++)
450 {
451 // ...
452 }
453 }
Timothy Warren82c83072012-01-26 19:02:05 -0500454
455 try {
456 // ...
457 }
458 catch() {
459 // ...
460 }
Derek Jones129c1812011-10-05 17:15:44 -0500461
462**CORRECT**::
463
464 function foo($bar)
465 {
466 // ...
467 }
468
469 foreach ($arr as $key => $val)
470 {
471 // ...
472 }
473
474 if ($foo == $bar)
475 {
476 // ...
477 }
478 else
479 {
480 // ...
481 }
482
483 for ($i = 0; $i < 10; $i++)
484 {
485 for ($j = 0; $j < 10; $j++)
486 {
487 // ...
488 }
489 }
Timothy Warren82c83072012-01-26 19:02:05 -0500490
491 try
492 {
493 // ...
494 }
495 catch()
496 {
497 // ...
498 }
Derek Jones8ede1a22011-10-05 13:34:52 -0500499
500Bracket and Parenthetic Spacing
501===============================
502
503In general, parenthesis and brackets should not use any additional
504spaces. The exception is that a space should always follow PHP control
505structures that accept arguments with parenthesis (declare, do-while,
506elseif, for, foreach, if, switch, while), to help distinguish them from
507functions and increase readability.
508
Derek Jones129c1812011-10-05 17:15:44 -0500509**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500510
Derek Jones129c1812011-10-05 17:15:44 -0500511 $arr[ $foo ] = 'foo';
512
513**CORRECT**::
514
515 $arr[$foo] = 'foo'; // no spaces around array keys
516
517**INCORRECT**::
518
519 function foo ( $bar )
520 {
521
522 }
523
524**CORRECT**::
525
526 function foo($bar) // no spaces around parenthesis in function declarations
527 {
528
529 }
530
531**INCORRECT**::
532
533 foreach( $query->result() as $row )
534
535**CORRECT**::
536
537 foreach ($query->result() as $row) // single space following PHP control structures, but not in interior parenthesis
Derek Jones8ede1a22011-10-05 13:34:52 -0500538
539Localized Text
540==============
541
542Any text that is output in the control panel should use language
543variables in your lang file to allow localization.
544
Derek Jones129c1812011-10-05 17:15:44 -0500545**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500546
Derek Jones129c1812011-10-05 17:15:44 -0500547 return "Invalid Selection";
548
549**CORRECT**::
550
551 return $this->lang->line('invalid_selection');
Derek Jones8ede1a22011-10-05 13:34:52 -0500552
553Private Methods and Variables
554=============================
555
556Methods and variables that are only accessed internally by your class,
557such as utility and helper functions that your public methods use for
558code abstraction, should be prefixed with an underscore.
559
560::
561
Derek Jones129c1812011-10-05 17:15:44 -0500562 convert_text() // public method
563 _convert_text() // private method
Derek Jones8ede1a22011-10-05 13:34:52 -0500564
565PHP Errors
566==========
567
568Code must run error free and not rely on warnings and notices to be
569hidden to meet this requirement. For instance, never access a variable
570that you did not set yourself (such as $_POST array keys) without first
571checking to see that it isset().
572
573Make sure that while developing your add-on, error reporting is enabled
574for ALL users, and that display_errors is enabled in the PHP
575environment. You can check this setting with::
576
Derek Jones129c1812011-10-05 17:15:44 -0500577 if (ini_get('display_errors') == 1)
578 {
579 exit "Enabled";
580 }
Derek Jones8ede1a22011-10-05 13:34:52 -0500581
582On some servers where display_errors is disabled, and you do not have
583the ability to change this in the php.ini, you can often enable it with::
584
585 ini_set('display_errors', 1);
586
587**NOTE:** Setting the
588`display_errors <http://us.php.net/manual/en/ref.errorfunc.php#ini.display-errors>`_
589setting with ini_set() at runtime is not identical to having it enabled
590in the PHP environment. Namely, it will not have any effect if the
591script has fatal errors
592
593Short Open Tags
594===============
595
596Always use full PHP opening tags, in case a server does not have
597short_open_tag enabled.
598
Derek Jones129c1812011-10-05 17:15:44 -0500599**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500600
Derek Jones129c1812011-10-05 17:15:44 -0500601 <? echo $foo; ?>
602
603 <?=$foo?>
604
605**CORRECT**::
606
607 <?php echo $foo; ?>
Derek Jones8ede1a22011-10-05 13:34:52 -0500608
609One Statement Per Line
610======================
611
612Never combine statements on one line.
613
Derek Jones129c1812011-10-05 17:15:44 -0500614**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500615
Derek Jones129c1812011-10-05 17:15:44 -0500616 $foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);
617
618**CORRECT**::
619
620 $foo = 'this';
621 $bar = 'that';
622 $bat = str_replace($foo, $bar, $bag);
Derek Jones8ede1a22011-10-05 13:34:52 -0500623
624Strings
625=======
626
627Always use single quoted strings unless you need variables parsed, and
628in cases where you do need variables parsed, use braces to prevent
629greedy token parsing. You may also use double-quoted strings if the
630string contains single quotes, so you do not have to use escape
631characters.
632
Derek Jones129c1812011-10-05 17:15:44 -0500633**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500634
Derek Jones129c1812011-10-05 17:15:44 -0500635 "My String" // no variable parsing, so no use for double quotes
636 "My string $foo" // needs braces
637 'SELECT foo FROM bar WHERE baz = \'bag\'' // ugly
638
639**CORRECT**::
640
641 'My String'
642 "My string {$foo}"
643 "SELECT foo FROM bar WHERE baz = 'bag'"
Derek Jones8ede1a22011-10-05 13:34:52 -0500644
645SQL Queries
646===========
647
648MySQL keywords are always capitalized: SELECT, INSERT, UPDATE, WHERE,
649AS, JOIN, ON, IN, etc.
650
651Break up long queries into multiple lines for legibility, preferably
652breaking for each clause.
653
Derek Jones129c1812011-10-05 17:15:44 -0500654**INCORRECT**::
Derek Jones8ede1a22011-10-05 13:34:52 -0500655
Derek Jones129c1812011-10-05 17:15:44 -0500656 // keywords are lowercase and query is too long for
657 // a single line (... indicates continuation of line)
658 $query = $this->db->query("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses
659 ...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");
660
661**CORRECT**::
662
663 $query = $this->db->query("SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz
664 FROM exp_pre_email_addresses
665 WHERE foo != 'oof'
666 AND baz != 'zab'
667 ORDER BY foobaz
668 LIMIT 5, 100");
Derek Jones8ede1a22011-10-05 13:34:52 -0500669
670Default Function Arguments
671==========================
672
673Whenever appropriate, provide function argument defaults, which helps
674prevent PHP errors with mistaken calls and provides common fallback
675values which can save a few lines of code. Example::
676
677 function foo($bar = '', $baz = FALSE)
678