个人工具
名字空间
变换
操作

Gallery:编码标准

来自站长百科
(版本间的差异)
跳转到: 导航, 搜索
 
第2行: 第2行:
  
 
==介绍==
 
==介绍==
The purpose of this document is to lay out a clear set of guidelines for developing code for the Gallery project. The scope of this document is limited mainly to PHP code, although Gallery will occasionally use SQL and HTML.
+
该文档的目的就是为Gallery代码的开发指明道路。该文档的着眼点主要限于PHP代码,尽管Gallery偶尔也会用到SQL和HTML。
  
 
===为何要进行编码转换?===
 
===为何要进行编码转换?===
Code conventions are important to programmers for a number of reasons:
+
代码转换对于程序员来说是很重要的,原因如下:
  
*80% of the lifetime cost of a piece of software goes to maintenance.
+
*软件使用80%时间都是用于维护的。
  
*Hardly any software is maintained for its whole life by the original author.
+
*几乎没有哪个软件终身维护都是由原编写者进行的。
  
*Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly. If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.
+
*代码转换提高了软件可读性,允许工程师能够更快更全面地理解新代码。如果你将源代码作为产品,那就的确保对其进行了较佳的包装而其清晰度也应与其他产品保持一致。
  
 
===感谢===
 
===感谢===
This document has been largely created by culling information from the following documents:
+
该文档的内容主要挑选自以下资料:
  
*[http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html Code Conventions for the JavaTM Programming Language]
+
*[http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html JavaTM编程语言的代码惯例]
  
*[http://pear.php.net/manual/en/standards.php Pear Coding Standards]
+
*[http://pear.php.net/manual/en/standards.php Pear编码标准]
  
*[http://area51.phpbb.com/docs/guide-standards.html phpBB Coding Standard Guidelines]
+
*[http://area51.phpbb.com/docs/guide-standards.html phpBB 编码标准指引]
  
 
*[http://www.phpdoc.de/doc PHPDoc]  
 
*[http://www.phpdoc.de/doc PHPDoc]  
  
In some places we've copied it verbatim. Please don't sue us, we've got no money anyway. If you modify and redistribute this document please maintain the above credits and give us some also. It was mostly written by Bharat Mediratta with input from Chris Smith, Matthew McEachen, Jesse Mullan and Beckett Madden-Woods. Try not to blame us too much for it.
+
其中的某些地方我们是照搬过来的。请不要因此起诉我们,我们完全没有商业动机。如果你对资料做了修改或重新分派的话,请在上面的致谢链接中进行修正维护。主编是Bharat Mediratta,由Chris Smith,Matthew McEachen,Jesse Mullan和Beckett Madden-Woods录入。请不要因此太过责难我们,很抱歉。
  
 
===编辑器设定/脚本===
 
===编辑器设定/脚本===
* [[Gallery2:VIM Editor Settings]]
+
* [[Gallery:VIM编辑器设定]]
* [[Gallery2:Kate Editor Settings]]
+
* [[Gallery:Kate编辑器设定]]
  
 
==缩进==
 
==缩进==
Four columns is the basic unit of indentation. The most efficient way to achieve this is to use a mixture of 8-column tabs and spaces, as in the example below:
+
缩进的基本单元是4个空格。达到此目的的最有效方法就是使用8空格制表宽度和空格的混合,如下所示:
  
 
  function myFunction() {
 
  function myFunction() {
     /* 4 spaces */
+
     /* 4个空格 */
 
     code;
 
     code;
 
     code;
 
     code;
 
   
 
   
 
     if (indentAnotherLevel) {
 
     if (indentAnotherLevel) {
         /* 8 spaces, or 1 tab */
+
         /* 8个空格,或1制表宽度 */
 
         moreCode;
 
         moreCode;
 
         moreCode;
 
         moreCode;
 
   
 
   
 
         if (indentAnotherLevel) {
 
         if (indentAnotherLevel) {
             /* 12 spaces, or 1 tab and 4 spaces */
+
             /* 12个空格,或1制表宽度加4个空格 */
 
             moreCode;
 
             moreCode;
 
             moreCode;
 
             moreCode;
第51行: 第51行:
 
  }
 
  }
  
Some people prefer to achieve 4 column indentation by having their editor define a tab as 4 columns. Do not do this when you edit Gallery code! This is bad because it requires everybody who views this file to redefine their tab character or the code does not appear the way you intended it to look. For example, other viewers like the sourceforge.net SVN browser, or via Unix utilities like "less" and "cat") will treat the tab as the standard 8 columns and now all your code will appear different. Stick with the standard 8 column tab.
+
某些人喜偏好编辑器定义1制表宽度为4空格。但在编辑Gallery代码时不要这么做!因为其他人要查看此文件的话就要重新定义制表字符或代码才能符合你的方式,这并不好。举个例子,其他如sourceforge.net SVN的浏览器,会将制表宽度理解为标准的8空格为单位,那么你所有的代码就会显得不一样了。所以请遵守标准的8空格的制表宽度。
  
Some editors, like Emacs and VI, will create this mixture of tabs and spaces for you automatically (in Emacs this is called "smart tabs" mode). This is more efficient than using only spaces because it cuts down considerably on the number of bytes in a file (since many lines of code will start with one or more levels of indentation). If for some reason your editor does not support smart tabs and you're finding it too difficult, you can use [[Image:Repair-indention.zip|this script]] to update files before commit.
+
某些如Emacs和VI的编辑器会自动为你创建这种混合的tab和空格(Emacs中这被称为"smart tabs"模式)。这比单纯使用空格要有效率的多,因为这能降低文件中的字节数(由于多行代码会具有一个或多个缩进级别)。如果出于某种原因,你的编辑器不支持smart tabs而你又觉着太麻烦,可以使用[[Image:Repair-indention.zip|这个脚本]]进行文件的更新。
  
 
===行长===
 
===行长===
Avoid lines greater than 100 characters. Yes, '''100''' not 80. We're in the new millenium now and we've got bigger screens.
+
避免每行超过100个字符。对,你没看错,是'''100'''而不是80。因为现在的电脑屏幕更“宽”更“大”了。
  
 
===包装行===
 
===包装行===
第200行: 第200行:
 
|}
 
|}
  
==类别及函数声明==
+
==Class and Function Declarations==
 
When coding classes and functions, the following formatting rules should be followed:  
 
When coding classes and functions, the following formatting rules should be followed:  
  

2008年10月28日 (二) 08:23的最后版本

Pages that need review by other documentation team members.

目录

介绍

该文档的目的就是为Gallery代码的开发指明道路。该文档的着眼点主要限于PHP代码,尽管Gallery偶尔也会用到SQL和HTML。

为何要进行编码转换?

代码转换对于程序员来说是很重要的,原因如下:

  • 软件使用80%时间都是用于维护的。
  • 几乎没有哪个软件终身维护都是由原编写者进行的。
  • 代码转换提高了软件可读性,允许工程师能够更快更全面地理解新代码。如果你将源代码作为产品,那就的确保对其进行了较佳的包装而其清晰度也应与其他产品保持一致。

感谢

该文档的内容主要挑选自以下资料:

其中的某些地方我们是照搬过来的。请不要因此起诉我们,我们完全没有商业动机。如果你对资料做了修改或重新分派的话,请在上面的致谢链接中进行修正维护。主编是Bharat Mediratta,由Chris Smith,Matthew McEachen,Jesse Mullan和Beckett Madden-Woods录入。请不要因此太过责难我们,很抱歉。

编辑器设定/脚本

缩进

缩进的基本单元是4个空格。达到此目的的最有效方法就是使用8空格制表宽度和空格的混合,如下所示:

function myFunction() {
   /* 4个空格 */
   code;
   code;

   if (indentAnotherLevel) {
       /* 8个空格,或1制表宽度 */
       moreCode;
       moreCode;

       if (indentAnotherLevel) {
           /* 12个空格,或1制表宽度加4个空格 */
           moreCode;
           moreCode;
       }
   }
}

某些人喜偏好编辑器定义1制表宽度为4空格。但在编辑Gallery代码时不要这么做!因为其他人要查看此文件的话就要重新定义制表字符或代码才能符合你的方式,这并不好。举个例子,其他如sourceforge.net SVN的浏览器,会将制表宽度理解为标准的8空格为单位,那么你所有的代码就会显得不一样了。所以请遵守标准的8空格的制表宽度。

某些如Emacs和VI的编辑器会自动为你创建这种混合的tab和空格(Emacs中这被称为"smart tabs"模式)。这比单纯使用空格要有效率的多,因为这能降低文件中的字节数(由于多行代码会具有一个或多个缩进级别)。如果出于某种原因,你的编辑器不支持smart tabs而你又觉着太麻烦,可以使用这个脚本进行文件的更新。

行长

避免每行超过100个字符。对,你没看错,是100而不是80。因为现在的电脑屏幕更“宽”更“大”了。

包装行

  • Break after a comma.
  • Break before an operator.
  • Prefer higher-level breaks to lower-level breaks.
  • Align the new line with the beginning of the expression at the same level on the previous line.
  • If the above rules lead to confusing code or to code that's squished up against the right margin, just indent 8 columns instead (not 4 columns).

Here are some examples of breaking method calls:

   someMethod(longExpression1, longExpression2, longExpression3,
       longExpression4, longExpression5);

   var = someMethod1(longExpression1,
       someMethod2(longExpression2,
           longExpression3));

Following are two examples of breaking an arithmetic expression. The first is preferred, since the break occurs outside the parenthesized expression, which is at a higher level.

   /* PREFER */
   longName1 = longName2 * (longName3 + longName4 - longName5) 
       + 4 * longname6;

   /* AVOID */
   longName1 = longName2 * (longName3 + longName4
       - longName5) + 4 * longname6;

Following are two examples of indenting function declarations. The first is the conventional case where the arguments are indented under the open parenthesis. In the second case, the function name is so long that indenting under the parenthesis would require us to put many parameters on their own line which is not visually appealing. But we can't indent the follow on lines by 4 columns because then it would be hard to differentiate them from the code that follows, so we indent them 8 columns, as we do when indenting wrapping if-clauses (see below).

   /* CONVENTIONAL INDENTATION */
   function someFunction($anArg, $anotherArg, $yetAnotherArg,
                         $andStillAnother) {
       codeHere;
   }
 
   /* INDENT 8 COLUMNS TO AVOID VERY DEEP INDENTS */
   function superExtraHorkingLongMethodName($anArg, $anArg, $anArg,
           $anotherArg, $yetAnotherArg, $yetMoreArg, $anArg, $anArg
           $andStillAnother) {
       codeHere;
   }

Line wrapping for if statements should generally use the 8 column rule, since conventional 4 column indentation makes it difficult to differentiate the predicate of the if-clause from its condition. For example:

   /* DON'T USE THIS INDENTATION */
   if ((condition1 && condition2)
       || (condition3 && condition4)
       ||!(condition5 && condition6)) { /* BAD WRAPS */
       doSomethingAboutIt();            /* MAKE THIS LINE EASY TO MISS */
   }

   /* USE THIS INDENTATION INSTEAD */
   if ((condition1 && condition2)
           || (condition3 && condition4)
           ||!(condition5 && condition6)) {
       doSomethingAboutIt();
   }

   /* OR USE THIS */
   if ((condition1 && condition2) || (condition3 && condition4)
           ||!(condition5 && condition6)) {
       doSomethingAboutIt();
   }

Expressions using the ternary operator should be parenthesized. Here are three acceptable ways to format ternary expressions:

   $alpha = (aLongBooleanExpression) ? $beta : $gamma;
         
   $alpha = (aLongBooleanExpression) ? $beta
                                     : $gamma;
         
   $alpha = (aLongBooleanExpression)
            ? $beta
            : $gamma;

行终结

Ensure that your editor is saving files in the Unix format. This means lines are terminated with a newline, not with a CR/LF combo as they are on Win32, or whatever the Mac uses. Any decent Win32 editor should be able to do this, but it might not always be the default. Know your editor.

命名惯例

Naming conventions make programs more understandable by making them easier to read. They can also give information about the function of the identifier-for example, whether it's a constant, package, or class-which can be helpful in understanding the code.

In the block below, we'll refer to a capitalization strategy called CamelCase. In this strategy, multiple words are combined into one where the beginning of each internal word is capitalized. Acronyms are capitalized like regular words.

There are two forms of CamelCase:

  • UpperCamelCase: The first letter is capitalized. (eg GalleryHelper, ImageLibrary)
  • lowerCamelCase: The first letter is not capitalized. (eg maximumCpuSpeed, isAcceptable)
Type Description Example
Files File names are in UpperCamelCase. Try to keep your file names simple and descriptive.

Files that can be viewed directly by the browser should terminate in .php or .html. Files that are only intended to be included or required, should end in .inc. This is a security precaution to prevent code from being run out of context. Files that contain a PHP class definition should end in .class, and should also contain a class of the same name as the file.

Exceptions: main.php, index.php, module.inc

ItemAdmin.inc

GalleryEntity.class

Classes Class names are in UpperCamelCase and should be nouns. Try to keep your class names simple and descriptive. Use whole words -- avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML and in that case, capitlize them as Url and Html). class GalleryMap

class UserDatabase
class UrlGenerator

Variables Variables are in lowerCamelCase. Private class members should start with an underscore (_), all other variable names should not start with an underscore.

Variable names should be short yet meaningful. The choice of a variable name should be mnemonic -- that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for temporary "throwaway" variables such as loop indexes. Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters.

var $fields;

var $userInformation;
var $_privateClassMember;

Functions Functions are in lowerCamelCase and should be verbs. Functions that return boolean values should be in the form of a question as in isEnabled. The noun-verb formation makes code easier to read, eg "Is the user enabled?" becomes if ($user->isEnabled). Private class methods should start with an underscore, all other methods and functions should never start with an underscore. function someFunction()

function publicMethod()
function _privateMethod()

Constants The names of variables declared class constants and of ANSI constants should be all uppercase with words separated by underscores (_) (ANSI constants should be avoided, for ease of debugging). Constants used in localization should begin with an underscore. $MIN_WIDTH = 4;

$FULL_ONLY_MODE = 2;

Database Tables Table names should use UpperCamelCase. Words should not be pluralized. User

UserGroupMap
ChildEntity

Database Fields Field names should use lowerCamelCase. Fields should avoid using numbers as this usually indicates failure to follow 3rd Normal Form (3NF). userName

modificationTimestamp
linkId

Class and Function Declarations

When coding classes and functions, the following formatting rules should be followed:

  • No space between a method name and the parenthesis "(" starting its parameter list
  • Open brace "{" appears at the end of the same line as the declaration statement
  • Closing brace "}" starts a line by itself indented to match its corresponding opening statement, except when it is a null statement the "}" should appear immediately after the "{"

The above rules are sometimes referred to as the K&R style. Example:

   class Foo {
       function getBar($a, $b) {}
   }

语句

简单语句

Each line should contain at most one statement. Example:

   $argv++;                /* Correct */
   $argc--;                /* Correct */
   $argv++; $argc--;       /* AVOID! */


复合语句

Compound statements are statements that contain lists of statements enclosed in braces "{ statements }".

The enclosed statements should be indented one more level than the compound statement. The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement. Braces are used around all statements, even single statements, when they are part of a control structure, such as an if-else or for statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces. Example:

   if ($a) {               /* Correct */
       b();
       c();
   }
   
   if ($a) {               /* Correct */
       b();
   }
   
   if ($a)                 /* AVOID! */
       b();
   
   if ($a) b();            /* AVOID! */

"return"语句

A return statement with a value should not use parentheses unless they make the return value more obvious in some way. Example:

   return;

   return myDisk.size();

   return (size ? size : defaultSize);


"if","if else","if else-if else"语句

The if-else class of statements should have the following form:

   if (condition) {
       statements;
   }

   if (condition) {
       statements;
   } else {
       statements;
   }

   if (condition) {
       statements;
   } else if (condition) {
       statements;
   } else {
       statements;
   }

Note: if statements always use braces {}. Avoid the following error-prone form:

   if (condition) /* AVOID! THIS OMITS THE BRACES {}! */
       statement;

"for"语句

A for statement should have the following form:

   for (initialization; condition; update) {
       statements;
   }

An empty for statement (one in which all the work is done in the initialization, condition, and update clauses) should have the following form:

   for (initialization; condition; update);

When using the comma operator in the initialization or update clause of a for statement, avoid the complexity of using more than three variables. If needed, use separate statements before the for loop (for the initialization clause) or at the end of the loop (for the update clause).

"while"语句

A while statement should have the following form:

   while (condition) {
       statements;
   }

An empty while statement should have the following form:

   while (condition);


"do-while"语句

A do-while statement should have the following form:

   do {
       statements; 
   } while (condition);


"switch"语句

A switch statement should have the following form:

   switch (condition) {
   case ABC:
       statements;
       /* falls through */

   case DEF:
       statements;
       break;

   case XYZ:
       statements;
       break;

   default:
       statements;
       break;
   }

Every time a case falls through (doesn't include a break statement), add a comment where the break statement would normally be. This is shown in the preceding code example with the /* falls through */ comment. Every switch statement should include a default case. The break in the default case is redundant, but it prevents a fall-through error if later another case is added.

空白行

Blank lines improve readability by setting off sections of code that are logically related. Two blank lines should always be used in the following circumstances:

  • Between sections of a source file
  • Between class and interface definitions

One blank line should always be used in the following circumstances:

  • Between methods
  • Between the local variables in a method and its first statement
  • Between logical sections inside a method to improve readability

空白处

Blank spaces should be used in the following circumstances: A keyword followed by a parenthesis should be separated by a space. Example:

   while (true) {
       ...
   }

Note that a blank space should not be used between a method name and its opening parenthesis. This helps to distinguish keywords from function calls. A blank space should appear after commas in argument lists. All binary operators except . should be separated from their operands by spaces. Blank spaces should never separate unary operators such as unary minus, increment ("++"), and decrement ("--") from their operands. Example:

   $a += $c + $d;
   $a = ($a + $b) / ($c * $d);
   while ($n < $s) {
       $n++;
   }
   print("size is " . $foo . "\n");

The expressions in a for statement should be separated by blank spaces. Example:

   for (expr1; expr2; expr3)

Casts should not be followed by a blank space. Examples:

   myFunction((int)$a, (int)$b);

批注

All code should be well commented. Good comments explain why a code is written in a particular way. You don't need to explain how it works -- that much we can figure out from reading the code. The reasoning behind your choices is the interesting part.

    /* This is a good single line comment */

    /*
     * This is a good block comment.  Note how the
     * Open and closing comment tokens are on their own lines.
     */

    // Bad -- no // style comments please.

    /* Bad block comments should have the open and closing
     * comment on their own line
     */

    /* Worse.  Block comments should have the open and closing
     * comment on their own line */
   

We prefer C-style block comments (/* */). USe of Perl/shell style comments (#) and C++ single line comments (//) are not allowed. Multiple line C style comments should see the asterisks aligned in a column (including the first line).

In addition, commenting any tricky, obscure, or otherwise not-immediately-obvious code is clearly something we should be doing. Especially important to document are any assumptions your code makes, or preconditions for its proper operation. Any one of the developers should be able to look at any part of the application and figure out what's going on in a reasonable amount of time.

分类/打包批注

These should appear at the beginning of every file, and help to explain the purpose of the file, and its place in the Gallery hierarchy. For example, the Gallery's core module is named the GalleryCore package. Files in the classes directory are part of the Classes subpackage. When these comments apply to classes, they become the class comments. Such a comment might look like:

   /**
    * Short explanation (1 line!)
    *
    * Some more text which explains in more detail what
    * the file does and who might be interested
    * in understanding that.
    *
    * @version $Id: coding-standards.xml,v 1.6 2005/05/22 22:54:29 bharat Exp $
    * @package GalleryCore
    * @subpackage Classes
    * @module GalleryModuleName
    */


  • The first line should be short but meaningful.
  • The longer explanation may span several lines. Currently HTML markup is not retained, so try to avoid it.
  • An @author statement might be present. see function comments below for details.
  • The @version statement should be used unchanged. Subversion will magically transform this into the actual version info of the file.
  • The @package statement identifies the file with its package.
  • The @subpackage statement further classifies the file.
  • The @module statement gives the file a more meaningful name. Usually it should be the filename without the suffix .php. Dots are not allowed in the name, so convert them to underscore if needed.

函数/方法批注

These explain in detail what a function does, what parameters it expects and what is returned by the function. Function comments apply to classes as well, here they magically turn into method comments. Such a comment appears directly above a function definition looks like this:

   /**
    * Short explanation (1 line!)
    *
    * Some more text which explains in more detail what
    * the function does and who might be interested
    * in understanding that.
    *
    * @author Name <email address>
    * @author Name2 <other email address>
    * @param type description
    * @return type description
    */
   function functionName( ...
  • The first line should be short but meaningful.
  • The longer explanation may span several lines. Currently HTML markup is not retained, so try to avoid it.
  • Use one @author statement per author, consisting of his/her name and optionally the email address in < and > signs. If given, the email address will be converted into a hyperlink automagically.
  • One or more @param statements describing the arguments the function expects. They must be given in the order in which they appear in the function definition. A @return statement, if the function returns something.

分类变量及包括文件批注

These are simple: They just quickly explain what a class varibale is used for, or what an included file does, or why we need it. These comments may be longer, if you have to explain more. They should appear just above the corresponding variable or include/require statement. They can be just one line and look like this:

   /**
    * Some explanation of the variable or file just below this comment.
    */

资料头

All files should contain the following text in a form where it will not interfere with the purpose of the file (i.e., commented out). In this example, it's presented in a commented out form for inclusion into PHP files.

   <?php 
   /* 
    * Gallery - a web based photo album viewer and editor 
    * Copyright (C) 2000-2006 Bharat Mediratta 
    * 
    * This program is free software; you can redistribute it and/or modify 
    * it under the terms of the GNU General Public License as published by 
    * the Free Software Foundation; either version 2 of the License, or (at 
    * your option) any later version. 
    * 
    * This program is distributed in the hope that it will be useful, but 
    * WITHOUT ANY WARRANTY; without even the implied warranty of 
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
    * General Public License for more details. 
    * 
    * You should have received a copy of the GNU General Public License 
    * along with this program; if not, write to the Free Software 
    * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA. 
    */ 
   ?>

特殊批注

Occasionally you wind up checking in code that's not totally satisfactory. Sometimes this is inevitable. In order to locate these bits of code so that we find and resolve it later, use the following tags in a comment, above the code in question:

  • REVISIT: this is an optimization waiting to happen, or something that could be improved on later. Optionally. If we're bored. And have itchy C-x v v fingers.
  • TODO: this is missing functionality (so by definition, it's broken) that needs to be addressed at some point.
  • FIXME: this is stubbed/broken functionality, but I need to commit. It can limp for now.

Keep in mind that you may not get back to this code for a while. You may not even be the one to fix the thing, so the more information that you provide while it's still fresh in your mind, the better. Potential solutions or workarounds are great, and may prove invaluable to whomever gets around to addressing the issue.

If the comment isn't clear it may be ignored and eventually deleted.

At some point in the future this will enable us to dictate the following:

  • No point release with FIXMEs
  • No major release with TODOs

PHP特定的指引行

Associative Array Keys In PHP, it's legal to use a literal string as a key to an associative array without quoting that string. We don't want to do this; the string should always be quoted to avoid confusion. Note that this is only when we're using a literal, not when we're using a variable. Examples:

   $foo = $assoc_array[blah];   /* WRONG */

   $foo = $assoc_array['blah']; /* RIGHT */


字串的引用

There are two different ways to quote strings in PHP - either with single quotes or with double quotes. The main difference is that the parser does variable interpolation in double-quoted strings, but not in single quoted strings. Because of this, you should always use single quotes unless you specifically need variable interpolation to be done on that string. This way, we can save the parser the trouble of parsing a bunch of strings where no interpolation needs to be done. Also, if you are using a string variable as part of a function call, you do not need to enclose that variable in quotes. Again, this will just make unnecessary work for the parser. Note, however, that nearly all of the escape sequences that exist for double-quoted strings will not work with single-quoted strings. Be careful, and feel free to break this guideline if it's making your code harder to read. Examples:

     /* WRONG */
     $str = "This is a really long string with no variables for the parser to find.";
     do_stuff("$str");

     /* RIGHT */
     $str = 'This is a really long string with no variables for the parser to find.';
     do_stuff($str);

Heredoc

Using the Heredoc string format is not recommended. One reason why is because it breaks the indention model.

包括代码

Anywhere you are unconditionally including a class file, use require_once(). Anywhere you are conditionally including a class file (for example, factory methods), use include_once(). Either of these will ensure that class files are included only once. They share the same file list, so you don't need to worry about mixing them. A file included with require_once() will not be included again by include_once().

Note: include_once() and require_once() are statements, not functions. You don't need parentheses around the filename to be included.

PHP代码标识

Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is the most portable way to include PHP code on differing operating systems and setups.

Uninitialized Variables

Don't use uninitialized variables. Gallery will use a high level of run-time error reporting. This will mean that the use of an uninitialized variable will be reported as an error. This will come up most often when checking which HTML form variables were passed. These errors can be avoided by using the built-in isset() function to check whether a variable has been set. Examples:

   /* old way */
   if ($forum) ...

   /* new way */
   if (isset($forum)) ...

杂项

魔术数字(Magic Numbers)

Don't use them. Use named constants for any literal value other than obvious special cases. Basically, it's OK to check if an array has 0 elements by using the literal 0. It's not OK to assign some special meaning to a number and then use it everywhere as a literal. This hurts readability and maintainability. Included in this guideline is that we should be using the constants true and false in place of the literals 1 and 0. Even though they have the same values, it's more obvious what the actual logic is when you use the named constants.

捷径算符

The only shortcut operators that cause readability problems are the shortcut increment ($i++) and decrement ($j--) operators. These operators should not be used as part of an expression. They can, however, be used on their own line. Using them in expressions is just not worth the headaches when debugging. Examples:

   /* WRONG */
   $array[++$i] = $j;
   $array[$i++] = $k;

   /* RIGHT */
   $i++;
   $array[$i] = $j;

   $array[$i] = $k;
   $i++;

算符优先

Do you know the exact precedence of all the operators in PHP? Neither do I. Don't guess. Always make it obvious by using brackets to force the precedence of an equation so you know what it does.

   /* what's the result? who knows. */
   $bool = ($i < 7 && $j > 8 || $k == 4);

   /* now you can be certain what I'm doing here. */
   $bool = ($i < 7 && ($j < 8 || $k == 4))

SQL代码布局

Capitalize the SQL keywords and put major keywords on their own lines. Don't put variables into your SQL, use markers instead. Use 2 column indentation. Put the entire query into a single multiline string where possible.

   /*
    * GOOD!.  This is an example of Gallery 2 SQL statements. 
    * In Gallery 2 we use an abstraction for table and column names so the syntax is slightly different
    * than it is with regular SQL statements.
    */
   $query = '
   SELECT
     [GalleryEntity::creationTimestamp],
     [GalleryEntity::modificationTimestamp]
   FROM
     [GalleryEntity]
   WHERE
     [GalleryEntity::id] = ?
     AND
     ([GalleryEntity::modificationTimestamp] > ?
      OR
      [GalleryEntity::creationTimestamp] > ?)
   ';
   /*
    * BAD!.  This example embeds a variable inside the query 
    * which is prone to SQL injection exploits, and puts the whole statement on a single line 
    * which is harder to parse visually. 
    */
   $query = "SELECT field1 FROM table a WHERE columnA = '$value'";

留言