PHP 源碼編碼標準

===========================================

PHP Coding Standards

PHP 源碼編碼標準

===========================================

This file lists several standards that any programmer adding or changing code in PHP should follow.

任何想要添加或更改PHP源碼的開發者都應該遵循這個文檔下面列出的幾個標準。

Since this file was added at a very late stage of the development of PHP v3.0,

這個文件從PHP v3.0版本的開發末期階段被添加

the code base does not (yet) fully follow it, but it’s going in that general direction

PHP的代碼還沒有完全遵循下面的標準, 但是會一直朝着這方向發展

Since we are now well into version 5 releases, many sections have been recoded to use these rules.

因爲現在PHP5已經發布了, 大部分已經遵循了下面的規則

===========================================

Code Implementation

代碼實現

===========================================

0. Document your code in source files and the manual. [tm]

在你的代碼源文件中提供技術手冊 [Technical Manual]

1. Functions that are given pointers to resources should not free them

給定的函數指針資源不應該free他們

For instance, ``function int mail(char *to, char *from)`` should NOT free to and/or from.
例如 function int mail(char *to, char *from) 不應該 free 參數 to 或 參數 from

Exceptions:
例外的情況:

- The function's designated behavior is freeing that resource E.g. efree()
- 函數本身被設計爲釋放資源 例如 efree()

- The function is given a boolean argument, that controls whether or not the function may free its arguments 
  給定的函數參數包含一個布爾值, 這個參數被用來控制是否釋放
  (if true - the function must free its arguments, if false - it must not)
  如果爲真 則函數釋放參數, 如果爲假 則不釋放

- Low-level parser routines, 
  that are tightly integrated with the token cache and the bison code for minimum memory copying overhead.
  與底層解析器程序緊密集成的令牌緩存或內存拷貝開銷最小的語法分析器生成器(GNU bison)代碼
  (可以理解爲C語言內嵌的一些彙編代碼)

2. Functions that are tightly integrated with other functions within the same module, and rely on each other non-trivial behavior, should be documented as such and declared ‘static’. They should be avoided if possible

在同一個模塊(module)中,函數應該彼此緊密集合,相互依賴的重要的功能應該用static聲明

3. Use definitions and macros whenever possible, so that constants have meaningful names and can be easily manipulated.

儘量使用定義和宏. 常量要起一個有意義的名字使代碼更容易被操作

The only exceptions to this rule are 0 and 1, when used as false and true (respectively).

0和1分別被當作false, true時可以例外

Any other use of a numeric constant to specify different behavior or actions should be done through a #define.
其他使用一個數字常量去指定不同行爲或動作的應該儘可能用 #define

4. When writing functions that deal with strings, be sure to remember that PHP holds the length property of each string,

當寫一個字符串處理函數時,一定要記得PHP每個字符串的長度屬性[要使用zend_parse_parameters_ex獲取到的字符串長度]

and that it shouldn’t be calculated with strlen().

而且不要用strlen來計算這個長度(如果不是\0結尾的字符串strlen的計算是不準確的)

Write your functions in such a way so that they’ll take advantage of the length property,

這樣在你的方法裏利用長度屬性

both for efficiency and in order for them to be binary-safe.

對效率和二進制安全都是有好處的

Functions that change strings and obtain their new lengths while doing so, should return that new length,

使用函數改變字符串並獲得他們的新長度的同時,應該返回新的長度

so it doesn’t have to be recalculated with strlen() (e.g. php_addslashes())

這樣就不用strlen重新計算了(例如 php_addslashes())

5. NEVER USE strncat(). If you’re absolutely sure you know what you’re doing,

絕對不要使用 strncat()函數. 如果你確定知道你在做什麼

check its man page again, and only then, consider using it, and even then, try avoiding it.

請再三查看該函數的使用手冊,想清楚再使用. 即使這樣也請儘量避免使用

6. Use PHP_* macros in the PHP source, and ZEND_* macros in the Zend part of the source.

在PHP的源碼部分使用宏 PHP_* , 在Zend引擎源碼部分使用宏 ZEND_*

Although the PHP_* macro’s are mostly aliased to the ZEND_* macros it gives a better

儘管幾乎所有的宏 PHP_* 只是宏 ZEND_* 的一個別名. 但是它可以使代碼的閱讀性更好,
understanding on what kind of macro you’re calling.

更容易理解你調用的是哪種宏

7. When commenting out code using a #if statement, do NOT use 0 only.

當註釋掉一段代碼的時候不要只使用 #if 0 來聲明.

Instead use “< git username here >_0”.

用git的賬號加_0 來代替

For example, #if FOO_0, where FOO is your git user foo.

例如 #if FOO_0, FOO表示你的git賬號

This allows easier tracking of why code was commented out, especially in bundled libraries.

這使得更容易跟蹤代碼被註釋掉了的原因, 尤其是在捆綁庫的時候

8. Do not define functions that are not available.

不要定義不可用的函數

For instance, if a library is missing a function, do not define the PHP version of the function,

例如 一個庫缺少一個函數或者這個函數沒有定義響應的PHP版本

and do not raise a run-time error about the function not existing.

如果在使用方法的時候也沒有報出方法不存在的運行時錯誤

End users should use function_exists() to test for the existence of a function

用戶需要使用 function_exists() 去測試這個方法是否存在

9. Prefer emalloc(), efree(), estrdup(), etc. to their standard C library counterparts.

emalloc(), efree(), estrdup() 等函數是對標準C庫的一個封裝.

These functions implement an internal “safety-net” mechanism that ensures the deallocation of any unfreed memory at the end of a request.

這些方法實現了一個內部安全的機制,以確保回收沒有被釋放的內存.

They also provide useful allocation and overflow information while running in debug mode.

而且這些函數在debug模式下還提供了非常有用的分配和溢出的信息

In almost all cases, memory returned to the engine must be allocated using emalloc().

在絕大多數情況下, 從內存到引擎必須使用 emalloc()函數來分配內存.

The use of malloc() should be limited to cases where a third-party library may need to control or free the memory,

只有在有限情況下才可能需要用malloc()等C庫函數來控制或釋放內存 比如使用第三方庫

or when the memory in question needs to survive between multiple requests.

或者當這塊內存的生命週期需要在多個請求中生存的時候

===========================================

User Functions/Methods Naming Conventions

用戶函數/方法名編碼約定

===========================================

1. Function names for user-level functions should be enclosed with in the PHP_FUNCTION() macro.

用戶級函數的函數名應該用封閉的PHP_FUNCTION()宏

**They should be in lowercase, with words underscore delimited, with care taken to minimize the letter count.**

函數名應該是小寫的,用字母和下劃線組合,儘量縮短函數名 

**Abbreviations should not be used when they greatly decrease the readability of the function name itself::**

但也不要用縮寫,會降低函數名本身的的可讀性 

Good:
'mcrypt_enc_self_test'
'mysql_list_fields'

Ok:
'mcrypt_module_get_algo_supported_key_sizes'
(could be 'mcrypt_mod_get_algo_sup_key_sizes'?)
'get_html_translation_table'
(could be 'html_get_trans_table'?)

Bad:
'hw_GetObjectByQueryCollObj'
'pg_setclientencoding'
'jf_n_s_i'

2. If they are part of a “parent set” of functions, that parent should be included in the user function name,

如果函數是父集的一部分, 父集名稱應該包含在這個函數名中

and should be clearly related to the parent program or function family. This should be in the form of parent_*::

並且應該明確該函數在父集中的關聯性, 應該用 parent_*:: 形式來命名

A family of 'foo' functions, for example:

Good:
'foo_select_bar'
'foo_insert_baz'
'foo_delete_baz'

Bad:
'fooselect_bar'
'fooinsertbaz'
'delete_foo_baz'

3. Function names used by user functions should be prefixed with _php_,

功能型內部使用的函數名應該加前綴_php_

and followed by a word or an underscore-delimited list of words, in lowercase letters, that describes the function.

緊隨其後的應該是一個單詞或用下劃線分割的一組詞, 並用小寫字母, 描述這個方法

If applicable, they should be declared ‘static’.

如果可以的話, 這裏儘量加static關鍵字 [這條可以去參考PHP源碼裏的_php_stream_write_buffer函數]

4. Variable names must be meaningful. One letter variable names must be avoided,

變量名必須是有意義的. 避免使用一個字母的變量名

except for places where the variable has no real meaning or a trivial meaning (e.g. for (i=0; i<100; i++) …).

除非這個變量名沒有實際意義或微不足道的意義. 例如for循環中的i

5. Variable names should be in lowercase. Use underscores to separate between words.

變量名應該用小寫字母. 詞與詞之間用下劃線分割

6. Method names follow the ‘studlyCaps’ (also referred to as ‘bumpy case’ or ‘camel caps’) naming convention,

方法名如’studlyCaps’(可參考駝峯命名法) 命名約定.

with care taken to minimize the letter count.

儘量簡化名字的字母個數

The initial letter of the name is lowercase, and each letter that starts a new ‘word’ is capitalized::

開頭的字母名字是小寫的並且名字新詞的首字母是大寫的

Good:
'connect()'
'getData()'
'buildSomeWidget()'

Bad:
'get_Data()'
'buildsomewidget'
'getI()'

7. Classes should be given descriptive names. Avoid using abbreviations where possible.

類應該給出描述性的名稱. 儘可能避免使用縮寫.

Each word in the class name should start with a capital letter, without underscore delimiters (CamelCaps starting with a capital letter).

每個詞的類名應該用大寫字母開始. 沒有下劃線分隔符(CamelCaps從一個大寫字母開始)

The class name should be prefixed with the name of the ‘parent set’ (e.g. the name of the extension)::

類名應該有”父集”的名稱前綴(例如擴展的名稱[可參考PDO的命名規則])

Good:
'Curl'
'FooBar'

Bad:
'foobar'
'foo_bar'

===========================================

Internal Function Naming Convensions

內部函數命名約定

===========================================

1. Functions that are part of the external API should be named ‘php_modulename_function()’ to avoid symbol collision.

爲了避免衝突,外部API函數應該用’php_modulename_function()’ 這種形式命名

They should be in lowercase, with words underscore delimited. Exposed API must be defined in ‘php_modulename.h’.

並且小寫,用下劃線分割. 對外暴露的API必須定義在你自己的 ‘php_modulename.h’頭文件中. 例如下面

PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);

Unexposed module function should be static and should not be defined in ‘php_modulename.h’.

不對外暴露的api不要定義在你的’php_modulename.h’ 頭文件中,而且應該用 static關鍵字修飾. 例如下面

static int php_session_destroy(TSRMLS_D)

2. Main module source file must be named ‘modulename.c’.

主模塊的源文件必須命名爲 ‘modulename.c’.[ modulename 是你自己起的模塊的名字 ]

3. Header file that is used by other sources must be named ‘php_modulename.h’.

主模塊的頭文件被包含在其他的源文件中,必須命名爲’php_modulename.h’.

===========================================

Syntax and indentation

語法和縮進

===========================================

1. Never use C++ style comments (i.e. // comment).

不要使用C++風格的註釋(也就是 // 註釋)

Always use C-style comments instead. PHP is written in C, and is aimed at compiling under any ANSI-C compliant compiler.

用C風格的註釋去代替它. PHP是用C寫的, 並且意圖在任何 ANSI-C 編譯器下編譯.

Even though many compilers accept C++-style comments in C code, you have to ensure that your code would compile with other compilers as well.

儘管許多編譯器能夠支持在C代碼中使C++風格的註釋, 但是爲了確保你的代碼兼容所有編譯器最好還是使用C風格的註釋

The only exception to this rule is code that is Win32-specific, because the Win32 port is MS-Visual C++ specific,

唯一例外的是在win32下的代碼, 因爲Win32 使用的是 MS-Visual C++ ,

and this compiler is known to accept C++-style comments in C code.

這個編譯器是明確支持在C代碼中使用C++風格註釋的

2. Use K&R-style. Of course, we can’t and don’t want to force anybody to use a style he or she is not used to,

使用K&R 風格. 當然 我們不能也不想強迫任何人用或不用這種風格

but, at the very least, when you write code that goes into the core of PHP or one of its standard modules,

但是 最起碼, 當你寫的代碼提交到PHP的核心 或 標準模塊之一

please maintain the K&R style.

請保持 K&R 風格

This applies to just about everything, starting with indentation and comment styles and up to function declaration syntax.

這種風格可以應用到所有事物中去, 上到函數聲明語法 下到縮進 註釋風格

Also see Indentstyle.

也可去看縮進風格

Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html

3. Be generous with whitespace and braces.

慷慨的空格和括號

Keep one empty line between the variable declaration section and the statements in a block,

變量的聲明和語句塊之間要保留一個空行,

as well as between logical statement groups in a block.

同樣在邏輯語句塊也要有空行

Maintain at least one empty line between two functions, preferably two. Always prefer::

保持兩個函數之間有一個空行,兩個更好

if (foo) {
    bar;
}

to:

if(foo)bar;

4. When indenting, use the tab character. A tab is expected to represent four spaces.

當使用tab製表符進行縮進的時候. 預計一個tab 佔用四個空格

It is important to maintain consistency in indenture so that definitions, comments, and control structures line up correctly.

重要的是在定義,註釋,和正確的控制結構體排列 要保持一致

5. Preprocessor statements (#if and such) MUST start at column one.

預處理語句(例如 #if)必須寫在第一列

To indent preprocessor directives you should put the # at the beginning of a line, followed by any number of whitespace.

如果要縮進預處理語句也要把 # 號放在一行的開始, 緊接着是任意數量的空格

===========================================

Testing

測試

===========================================

1. Extensions should be well tested using *.phpt tests. Read about that in README.TESTING.

PHP擴展應該用*.phpt 來測試. 請閱讀 README.TESTING.

===========================================

Documentation and Folding Hooks

文檔和可摺疊鉤子

===========================================

In order to make sure that the online documentation stays in line with the code,

爲了確保在線文檔與代碼保持一致

each user-level function should have its user-level function prototype before it along with a brief one-line description of what the function does.

每個用戶級函數在有它的用戶級函數原型之前,應該有一行簡單的對函數的描述。

It would look like this::

它看起來應該是這樣的::

/* {{{ proto int abs(int number)
 Returns the absolute value of the number */
PHP_FUNCTION(abs)
{
 ...
}
/* }}} */

The {{{ symbols are the default folding symbols for the folding mode in Emacs and vim (set fdm=marker).

在Emacs 和 vim 中 符號 {{{ 在摺疊模式下 默認是摺疊符號 (set fdm=marker)

Folding is very useful when dealing with large files because you can scroll through the file quickly and just unfold the function you wish to work on.

在處理大文件的時候摺疊是非常有用的, 因爲你能快速滾動文件並展開你希望工作的功能

The }}} at the end of each function marks the end of the fold, and should be on a separate line.

符號 }}} 在每個函數的結尾標誌着摺疊的結束, 並且應該在單獨的一行

The “proto” keyword there is just a helper for the doc/genfuncsummary script which generates a full function summary.

那裏的”原型”關鍵字只是輔助doc/genfuncsummary腳本生成所有函數摘要的

Having this keyword in front of the function prototypes allows us to put folds elsewhere in the code without messing up the function summary.

該關鍵字在函數原型的前面允許我們放在摺疊塊裏,不影響函數摘要

Optional arguments are written like this::

可選參數像下面這樣寫::

/* {{{ proto object imap_header(int stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
Returns a header object with the defined parameters */

And yes, please keep the prototype on a single line, even if that line is massive.

沒錯, 請保持原型在單獨的一行, 即使這行可能會很長.

===========================================

New and Experimental Functions

新的 實驗性的函數

===========================================

To reduce the problems normally associated with the first public implementation of a new set of functions,

在首次公開一套新的函數集實現時 爲了減少相關問題

it has been suggested that the first implementation include a file labeled ‘EXPERIMENTAL’ in the function directory,

有人建議 在這個函數的目錄包含一個有“實驗”標籤的文件

and that the functions follow the standard prefixing conventions during their initial implementation.

並且這個函數在最初實現的時候要遵循下面的標準前綴約定

The file labelled ‘EXPERIMENTAL’ should include the following information::

含有”實驗”標籤的文件應包括以下信息

Any authoring information (known bugs, future directions of the module).

在git的提交信息中要包括 作者信息(已知的bugs, 這個模塊的特性指示)

Ongoing status notes which may not be appropriate for Git comments.

持續的狀態記錄以及不適用的狀況

In general new features should go to PECL or experimental branches until there are specific reasons for directly adding it to the core distribution.

一般新特性應該提交到PECL或實驗分支,除非有特殊原因會直接添加到核心發佈

===========================================

Aliases & Legacy Documentation

別名 & 遺留文檔

===========================================

You may also have some deprecated aliases with close to duplicate names, for example, somedb_select_result and somedb_selectresult.

你也可能有一些棄用的別名或接近重複的名字, 例如 somedb_select_result and somedb_selectresult

For documentation purposes, these will only be documented by the most current name, with the aliases listed in the documentation for the parent function.

一些人只會記錄最新的名字, 別名會記錄在父函數的文檔列表中

For ease of reference, user-functions with completely different names, that alias to the same function (such as highlight_file and show_source), will be separately documented.

爲了便於參考, 這種用戶層函數名字完全不同, 別名是同樣的方法將被分別記錄.

The proto should still be included, describing which function is aliased.

描述函數別名的原型仍應包括在內

Backwards compatible functions and names should be maintained as long as the code can be reasonably be kept as part of the codebase.

只要這部分代碼能夠被維護, 功能和名稱應該儘可能保持向後兼容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章