文档仓库地址:https://github.com/hfcorriez/fig-standards
PSR规范中文版
复制代码 代码如下:
在谷歌,我可以查看任何的代码,进入所有谷歌的代码库,我有权查看它们。事实上,这种权限是很少人能拥有的。但是,让我感到惊讶的却是,如此多的编码规范—缩进,命名,文件结构,注释风格—这一切让我出乎意料的轻松的阅读任意一段代码,并轻易的看懂它们。这让我震惊—因为我以为这些规范是微不足道的东西。它们不可能有这么大的作用—但它们却起到了这么大的作用。当你发现只通过看程序的基本语法结构就能读懂一段代码,这种时间上的节省不能不让人震撼!
1.1. 示例
本示例包含上面的一些规则简单展示:
复制代码 代码如下:
namespace Vendor\Package;
use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class Foo extends Bar implements FooInterface
{
public function sampleFunction($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// method body
}
}
2. 概括
2.1 基础代码规范
代码必须遵守 PSR-1 的所有规则。
2.2 文件
所有的PHP文件必须使用Unix LF(换行)作为行结束符。
所有PHP文件必须以一个空行结束。
纯PHP代码的文件关闭标签?>必须省略
2.3. 行
行长度不可有硬限制。
行长度的软限制必须是120个字符;对于软限制,自动样式检查器必须警告但不可报错。
行实际长度不应超过80个字符;较长的行应当被拆分成多个不超过80个字符的后续行。
在非空行后面不可有空格。
空行可以用来改善可读性和区分相关的代码块。
一行不应多于一个语句。
2.4. 缩进
代码必须使用4个空格的缩进,并且不可使用制表符作为缩进。
注意:只用空格,不和制表符混合使用,将会对避免代码差异,补丁,历史和注解中的一些问题有帮助。使用空格还可以使调整细微的缩进来改进行间对齐变得非常简单。
2.5. 关键词和 True/False/Null
PHP keywords 必须使用小写。
PHP常量true, false和null必须使用小写。
3. Namespace和Use声明
如果存在,namespace声明之后必须有一个空行。
如果存在,所有的use声明必须放在namespace声明的下面。
一个use关键字必须只用于一个声明。
在use声明代码块后面必须有一个空行。
示例:
复制代码 代码如下:
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
// ... additional PHP code ...
4. 类,属性和方法
术语“类”指所有的类,接口和特性(traits)。
4.1. 扩展和继承
一个类的extends和implements关键词必须和类名在同一行。
类的左花括号必须放在下面自成一行;右花括号必须放在类主体的后面自成一行。
复制代码 代码如下:
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// constants, properties, methods
}
implements一个列表可以被拆分为多个有一次缩进的后续行。如果这么做,列表的第一项必须要放在下一行,并且每行必须只有一个接口。
复制代码 代码如下:
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// constants, properties, methods
}
4.2. 属性
所有的属性必须声明可见性。
var关键词不可用来声明属性。
一个语句不可声明多个属性。
属性名称不应使用单个下划线作为前缀来表明保护或私有的可见性。
一个属性声明看起来应该下面这样的。
复制代码 代码如下:
namespace Vendor\Package;
class ClassName
{
public $foo = null;
}
4.3. 方法
所有的方法必须声明可见性。
方法名不应只使用单个下划线来表明是保护或私有的可见性。
方法名在声明之后不可跟随一个空格。左花括号必须放在下面自成一行,并且右花括号必须放在方法主体的下面自成一行。左括号后面不可有空格,右括号前面不可有空格。
一个方法定义看来应该像下面这样。 注意括号,逗号,空格和花括号:
复制代码 代码如下:
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// method body
}
}
4.4. メソッドパラメータ
パラメータリストでは、カンマの前にスペースを入れてはならず、カンマの後にはスペースを 1 つ入れる必要があります。
メソッド内のデフォルト値を持つパラメーターは、パラメーター リストの最後に配置する必要があります。
コードをコピー コードは次のとおりです:
namespace VendorPackage;
class ClassName
{
public function foo($arg1, &$arg2, $arg3 = [])
{
// メソッド本体
}
}
パラメータ リストは、1 つのインデントで後続の複数の行に分割できます。これを行う場合、リストの最初の項目を次の行に配置し、各行にパラメータを 1 つだけ配置する必要があります。
パラメータリストが複数行に分かれている場合は、右括弧と左中括弧をスペースで区切ってそれぞれの行を形成する必要があります。
コードをコピー コードは次のとおりです:
namespace VendorPackage;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
) array $arg3 = []
) {
//メソッド本体
}
}
4.5. abstract、final、static
存在する場合、abstract 宣言と Final 宣言は可視性宣言の前に配置する必要があります。
存在する場合、静的宣言の後には可視性宣言が続く必要があります。
コードをコピー コードは次のとおりです:
namespace VendorPackage;
抽象クラス ClassName
{
protected static $foo;
抽象保護関数 zim();
Final public static function bar()
{
// メソッド本体
}
}
4.6. メソッドと関数の呼び出し
メソッドまたは関数を呼び出すには、メソッドまたは関数名と左括弧の間にスペース、左括弧の後にスペース、右括弧の前にスペースを入れてはいけません。関数リストでは、カンマの前にスペースがあってはならず、カンマの後にスペースが 1 つ必要です。
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
パラメータ リストはインデントを使用して後続の行に分割します。これを行う場合、リストの最初の項目を次の行に配置し、各行に引数を 1 つだけ指定する必要があります。
コードをコピー コードは次のとおりです:
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
5. コントロール構造
コントロール構造のスタイル規則は次のように要約されます:
制御構造キーワードの後にスペースが必要です
左括弧の後にスペースがあってはなりません
右括弧の前にスペースがあってはなりません
右括弧とキーワードの間にスペースが必要です左中括弧
コード 本体は 1 回インデントする必要があります
閉じ中括弧は本体の 1 行下にある必要があります
各構造体の本体は中括弧で囲む必要があります。この構造はより標準化されているように見え、新しい行を追加するときにエラーが発生する可能性が低くなります。
5.1. if、elseif、else
if 構造は次のようになります。括弧、スペース、中括弧の配置に注意してください。else と elseif は前の本文の閉じ中括弧と同じ行にあります。
コードをコピー コードは次のとおりです:
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
すべての制御キーワードを 1 つの単語として保持するには、else if の代わりにキーワード elseif を使用する必要があります。
5.2. スイッチ、ケース
スイッチ構造は次のようになります。括弧、スペース、中括弧に注意してください。 case ステートメントはスイッチからインデントする必要があり、break キーワード (または他の Break キーワード) はケース本体と同じレベルでインデントする必要があります。空ではないケース本体が落ちた場合は、// no Break のようなコメントが必要です。
コードをコピー コードは次のとおりです:
switch ($expr) {
case 0:
echo 'First case, with a break';
break;
case 1:
echo 'Second case, which falls through';
// no break
case 2:
case 3:
case 4:
echo 'Third case, return instead of break';
return;
default:
echo 'Default case';
break;
}
复制代码 代码如下:
while ($expr) {
// structure body
}
复制代码 代码如下:
do {
// structure body;
} while ($expr);
5.4. for
一个for语句看起来应该像下面这样。注意括号,空格和花括号的位置。
复制代码 代码如下:
for ($i = 0; $i < 10; $i++) {
// for body
}
5.5. foreach
一个foreach语句看起来应该像下面这样。注意括号,空格和花括号的位置。
复制代码 代码如下:
foreach ($iterable as $key => $value) {
// foreach body
}
复制代码 代码如下:
try {
// try body
} catch (FirstExceptionType $e) {
// catch body
} catch (OtherExceptionType $e) {
// catch body
}
6. 闭包
闭包在声明时function关键词之后必须有一个空格,并且use之前也需要一个空格。
左花括号必须在同一行,右花括号必须在主体的下一行。
参数列表和变量列表的左括号之后不可有空格,其右括号之前也不可有空格。
在参数列表和变量列表中,逗号之前不可有空格,逗号之后必须有空格。
闭包带默认值的参数必须放在参数列表后面。
一个闭包声明看起来应该像下面这样。注意括号,空格和花括号的位置。
复制代码 代码如下:
$closureWithArgs = function ($arg1, $arg2) {
// body
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};
参数和变量列表可以被分成多个带一次缩进的后续行。如果这么做,列表的第一项必须放在下一行,并且一行必须只放一个参数或变量。
当最终列表(不管是参数还是变量)被分成多行,右括号和左花括号必须夹带一个空格放在一起自成一行。
下面是一个参数和变量列表被分割成多行的示例。
复制代码 代码如下:
$longArgs_noVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) {
// body
};
$noArgs_longVars = function () use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_shortVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use ($var1) {
// body
};
$shortArgs_longVars = function ($arg) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
复制代码 代码如下:
$foo->bar(
$arg1,
function ($arg2) use ($var1) {
// body
},
$arg3
);
7. 结论
在该指南中有很多风格的元素和做法有意被忽略掉。这些包括但不局限于:
全局变量和全局常量的声明
方法声明
操作符和赋值
行间对齐
注释和文档块
类名给你前缀和后缀
最佳实践
以后的建议可以修改和扩展该指南以满足这些或其他风格的元素和实践。
附录A 调查
为了写这个风格指南,我们采用了调查个项目以确定共同的做法。这个调查在这里供他人查看。
A.1. 调查数据
url,http://www.horde.org/apps/horde/docs/CODING_STANDARDS,http://pear.php.net/manual/en/standards.php,http://solarphp.com/manual/appendix-standards.style,http://framework.zend.com/manual/en/coding-standard.html,http://symfony.com/doc/2.0/contributing/code/standards.html,http://www.ppi.io/docs/coding-standards.html,https://github.com/ezsystems/ezp-next/wiki/codingstandards,http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html,https://github.com/UnionOfRAD/lithium/wiki/Spec%3A-Coding,http://drupal.org/coding-standards,http://code.google.com/p/sabredav/,http://area51.phpbb.com/docs/31x/coding-guidelines.html,https://docs.google.com/a/zikula.org/document/edit?authkey=CPCU0Us&hgd=1&id=1fcqb93Sn-hR9c0mkN6m_tyWnmEvoswKBtSc0tKkZmJA,http://www.chisimba.com,n/a,https://github.com/Respect/project-info/blob/master/coding-standards-sample.php,n/a,Object Calisthenics for PHP,http://doc.nette.org/en/coding-standard,http://flow3.typo3.org,https://github.com/propelorm/Propel2/wiki/Coding-Standards,http://developer.joomla.org/coding-standards.html
voting,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,no,no,no,?,yes,no,yes
indent_type,4,4,4,4,4,tab,4,tab,tab,2,4,tab,4,4,4,4,4,4,tab,tab,4,tab
line_length_limit_soft,75,75,75,75,no,85,120,120,80,80,80,no,100,80,80,?,?,120,80,120,no,150
line_length_limit_hard,85,85,85,85,no,no,no,no,100,?,no,no,no,100,100,?,120,120,no,no,no,no
class_names,studly,studly,studly,studly,studly,studly,studly,studly,studly,studly,studly,lower_under,studly,lower,studly,studly,studly,studly,?,studly,studly,studly
class_brace_line,next,next,next,next,next,same,next,same,same,same,same,next,next,next,next,next,next,next,next,same,next,next
constant_names,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper
true_false_null,lower,lower,lower,lower,lower,lower,lower,lower,lower,upper,lower,lower,lower,upper,lower,lower,lower,lower,lower,upper,lower,lower
method_names,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel,lower_under,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel
method_brace_line,next,next,next,next,next,same,next,same,same,same,same,next,next,same,next,next,next,next,next,same,next,next
control_brace_line,same,same,same,same,same,same,next,same,same,same,same,next,same,same,next,same,same,same,same,same,same,next
control_space_after,yes,yes,yes,yes,yes,no,yes,yes,yes,yes,no,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes
always_use_control_braces,yes,yes,yes,yes,yes,yes,no,yes,yes,yes,no,yes,yes,yes,yes,no,yes,yes,yes,yes,yes,yes
else_elseif_line,same,same,same,same,same,same,next,same,same,next,same,next,same,next,next,same,same,same,same,same,same,next
case_break_indent_from_switch,0/1,0/1,0/1,1/2,1/2,1/2,1/2,1/1,1/1,1/2,1/2,1/1,1/2,1/2,1/2,1/2,1/2,1/2,0/1,1/1,1/2,1/2
function_space_after,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no
closing_php_tag_required,no,no,no,no,no,no,no,no,yes,no,no,no,no,yes,no,no,no,no,no,yes,no,no
line_endings,LF,LF,LF,LF,LF,LF,LF,LF,?,LF,?,LF,LF,LF,LF,?,,LF,?,LF,LF,LF
static_or_visibility_first,static,?,static,either,either,either,visibility,visibility,visibility,either,static,either,?,visibility,?,?,either,either,visibility,visibility,static,?
control_space_parens,no,no,no,no,no,no,yes,no,no,no,no,no,no,yes,?,no,no,no,no,no,no,no
blank_line_after_php,no,no,no,no,yes,no,no,no,no,yes,yes,no,no,yes,?,yes,yes,no,yes,no,yes,no
class_method_control_brace,next/next/same,next/next/same,next/next/same,next/next/same,next/next/same,same/same/same,next/next/next,same/same/same,same/same/same,same/same/same,same/same/same,next/next/next,next/next/same,next/same/same,next/next/next,next/next/same,next/next/same,next/next/same,next/next/same,same/same/same,next/next/same,next/next/next
A.2. 调查说明
indent_type: 缩进类型。 tab = "使用制表符",2 or 4 = "空格数量"
line_length_limit_soft: 行长度的“软”限制,用字符。 ? = 不表示或者数字 no 意为不限制.
line_length_limit_hard: 行长度的"硬"限制,用字符。 ? = 不表示或者数字, no 意为不限制.
class_names: 类名如何命名 lower = 只是小写, lower_under = 小写加下划线, studly = 骆驼型.
class_brace_line: 类的左花括号是放在同(same)一行还是在下(next)一行?
constant_names: 类常量如何命名?upper = 大写加下划线分隔符。
true_false_null: 全校写或者全大写?
method_names: 方法名如何命名?camel = 驼峰式, lower_under = 小写加下划线分隔符。
method_brace_line: 方法的左花括号在同(same)一行还是在下(next)一行?
control_brace_line: 控制结构的左花括号在同(same)一行还是在下(next)一行?
control_space_after: 控制结构关键词后是否有空格?
always_use_control_braces: 制御構造には常に中括弧を使用しますか?
else_elseif_line: else と elseif を使用する場合、同じ行に配置する必要がありますか、それとも次の行に配置する必要がありますか?
case_break_indent_from_switch: case と Break は switch ステートメントから何回インデントされますか?
function_space_after: 関数名と関数呼び出しの左括弧にスペースはありますか?
closed_php_tag_required: 純粋な PHP ファイルの場合、タグを閉じますか?>必須ですか?
line_endings: どの行末を使用するか?
static_or_visibility_first: メソッドを定義するときに、静的と可視性のどちらが先に来ますか?
control_space_parens: 制御構造式で、左括弧の後と右括弧の前にスペースがありますか?はい = if ( $expr )、いいえ = if ($expr).
blank_line_after_php: PHP の開始タグの後に空行は必要ですか?
class_method_control_brace: クラス、メソッド、および制御構造内の左中括弧の位置。
A.3. 調査結果
indent_type:
tab: 7
2: 1
4: 14
line_length_limit_soft:
?: 2
no: 3
75: 4
80: 6
85: 1
100: 1
120: 4
150: 1
line_length_limit_hard:
?: 2
いいえ: 11
85: 4
100: 3
120: 2
class_names:
?: 1
lower: 1
lower_under: 1
スタッド: 19
class_brace_line:
次: 16
同じ: 6
constant_names:
上位: 22
true_false_null:
下位: 19
上位: 3
method_names: Camel: 21
LOWER_UNDER: 1
Method_brace_line:
Next: 15
Same: 7
Control_line_line:
NEXT: 4
Same: 18
Control_SPACE _After :
いいえ: 2
はい: 20
always_use_control_braces:
いいえ: 3
はい: 19
else_elseif_line:
次: 6
同じ: 16
case_break_in dent_from_switch :
0/1: 4
1/1: 4
1/2: 14
function_space_after:
no: 22
closed_php_tag_required:
no: 19
はい: 3
line_endings:
?: 5
LF: 17
static_or_visibility_first:
?: 5
いずれか: 7
static: 4
可視性: 6
control_space_parens:
?: 1
いいえ: 19
はい: 2
blank_line_after_php:
?: 1
いいえ: 13
はい: 8
class_method_control_ ブレース:
次/次/次: 4
次/次/同じ: 11
次/同じ/同じ: 1
同じ/同じ/同じ: 6