惯例及编码风格

我们鼓励您在编码的过程中遵循和Kohana一致的编码风格,因为这样不仅增强了代码的可读性,而且便于您的代码更容易地分享和贡献出去。原文

类命名方式及对应文件位置

在Kohana里,类名都遵循着一个严格的约定以便于自动加载。类名中需要区分的单词要用下划线来分割,同时单词的首字母须大写。下划线十分重要,因为它们直接反映了文件在文件系统中的位置。原文

以下惯用法适用:原文

  1. 类名最好不要使用驼峰规则,除非你不想创建更深层次的目录。原文
  2. 所有类的文件名和目录命都必须小写。原文
  3. 所有的类文件都应该存储于 classes目录之下,而无论该类文件位于该层级文件系统下面的第几层。原文

例子 {#class-name-examples}

记住,在一个类的名称里一个下划线就意味着一个新的子目录,请参考下面的例子:原文

类名 文件路径
Controller_Template classes/controller/template.php
Model_User classes/model/user.php
Database classes/database.php
Database_Query classes/database/query.php
Form classes/form.php

编码标准

为了写出高度一致性的源代码,我们要求每一个人尽量遵循编码标准。原文

括号

请使用BSD/Allman 风格 bracketing.

花括号

花括号被置于单独的行,并且和控制语句保持同样的缩进。原文

  1. // 正确
  2. if ($a === $b)
  3. {
  4. ...
  5. }
  6. else
  7. {
  8. ...
  9. }
  10. // 错误
  11. if ($a === $b) {
  12. ...
  13. } else {
  14. ...
  15. }

类的括号

花括号使用规则的唯一例外是,类定义时左花括号应位于类名的同一行。原文

  1. // 正确
  2. class Foo {
  3. // 不正确
  4. class Foo
  5. {

空括号

空括号之间不需要任何字符,留空即可。原文

  1. // Correct
  2. class Foo {}
  3. // Incorrect
  4. class Foo { }

数组的括号

数组的括号应该在一行上,或者在多行。原文

  1. array('a' => 'b', 'c' => 'd')
  2. array(
  3. 'a' => 'b',

javascript:void(0); ‘c’ => ‘d’, )

左括号

数组的左括号应位于array关键词的同一行。原文

  1. // 正确
  2. array(
  3. ...
  4. )
  5. // 不正确:
  6. array
  7. (
  8. ...
  9. )
右括号
一维数组

由多行组成的一维数组的右括号应独占一行,并且保持与赋值语句一致的缩进。原文

  1. // 正确
  2. $array = array(
  3. ...
  4. )
  5. // 不正确
  6. $array = array(
  7. ...
  8. )
多维数组

嵌套数组向右缩进一个制表位,其余格式则遵循一维数组的规则。原文

  1. // 正确
  2. array(
  3. 'arr' => array(
  4. ...
  5. ),
  6. 'arr' => array(
  7. ...
  8. ),
  9. )
  10. array(
  11. 'arr' => array(...),
  12. 'arr' => array(...),
  13. )
数组作为函数实参
  1. // 正确
  2. do(array(
  3. ...
  4. ))
  5. // 不正确
  6. do(array(
  7. ...
  8. ))

正如对数组的左括号的注解,单行语法在这里同样生效。原文

  1. // 正确
  2. do(array(...))
  3. // 实参较长时的另一种选择
  4. do($bar, 'this is a very long line',
  5. array(...));

命名惯例

Kohana使用下划线命名方式,而非驼峰命名规则。原文

  1. // 控制器类,使用 Controller_ 作为前缀
  2. class Controller_Apple extends Controller {
  3. // 模型类,使用 Model_ 作为前缀
  4. class Model_Cheese extends Model {
  5. // 普通累
  6. class Peanut {

在创建类实例时,不要使用圆括号除非你要给构造函数传递实参。原文

  1. // 正确:
  2. $db = new Database;
  3. // 不正确:
  4. $db = new Database();

函数和方法

所有函数名都必须小写并且使用下划线来分隔单词:原文

  1. function drink_beverage($beverage)
  2. {

变量

所有变量都应该小写,并且要使用下划线而不是驼峰规则来分隔变量名中的单词:原文

  1. // 正确:
  2. $foo = 'bar';
  3. $long_example = 'uses underscores';
  4. // 不正确:
  5. $weDontWantThis = 'understood?';

缩进

你必须使用制表符Tab来缩进你的代码,反之使用空格来进行则是被严格禁止的。原文

垂直间距(对多行而言)由空格来完成,而制表符Tab则不适合垂直对齐,因为不同人的制表宽度并不一致。原文

  1. $text = 'this is a long text block that is wrapped. Normally, we aim for '
  2. .'wrapping at 80 chars. Vertical alignment is very important for '
  3. .'code readability. Remember that all indentation is done with tabs,'
  4. .'but vertical alignment should be completed with spaces, after '
  5. .'indenting with tabs.';

字符串连接

不要将空格置于字符串连接符的周围:原文

  1. // 正确:
  2. $str = 'one'.$var.'two';
  3. // 不正确:
  4. $str = 'one'. $var .'two';
  5. $str = 'one' . $var . 'two';

单行语句

单行if语句应该只在需要打断正常执行流程时使用:原文

  1. // 可接受的:
  2. if ($foo == $bar)
  3. return $foo;
  4. if ($foo == $bar)
  5. continue;
  6. if ($foo == $bar)
  7. break;
  8. if ($foo == $bar)
  9. throw new Exception('You screwed up!');
  10. // 不可接受的:
  11. if ($baz == $bun)
  12. $baz = $bar + 2;

比较运算符

请使用OR和AND来做比较运算符:原文

  1. // 正确:
  2. if (($foo AND $bar) OR ($b AND $c))
  3. // 不正确:
  4. if (($foo && $bar) || ($b && $c))

请使用elseif,而非else if:原文

  1. // 正确:<!--: test -->
  2. elseif ($bar)
  3. // 不正确:
  4. else if($bar)

Switch结构

case,break及default都应独占一行,同时case和default区块内容均需要缩进一个tab制表符。原文

  1. switch ($var)
  2. {
  3. case 'bar':
  4. case 'foo':
  5. echo 'hello';
  6. break;
  7. case 1:
  8. echo 'one';
  9. break;
  10. default:
  11. echo 'bye';
  12. break;
  13. }

圆括号

判断语句关键字和左圆括号之间应使用一个空格来分隔,字符!(惊叹号)两边都必须要有一个空格来隔开以使可读性最大化。例外的是单独的惊叹号和类型转换操作,在这两种情况下的左括号之后和右括号之前都不需要任何空格。原文

  1. // 正确:
  2. if ($foo == $bar)
  3. if ( ! $foo)
  4. // 不正确:
  5. if($foo == $bar)
  6. if(!$foo)
  7. if ((int) $foo)
  8. if ( $foo == $bar )
  9. if (! $foo)

三元运算符

所有的三元操作符都应该遵循一个标准格式。圆括号只能用于完整的表达式而不是只将变量括起来。原文

  1. $foo = ($bar == $foo) ? $foo : $bar;
  2. $foo = $bar ? $foo : $bar;

所有的比较和操作符必须在一组圆括号内部进行:原文

  1. $foo = ($bar > 5) ? ($bar + $foo) : strlen($bar);

如要将复杂的三元运算表达式拆分成多行(三元表达式的第一部分超过了80个字符),则需在连续行的运算符的前面使用空格来排列这些运算符:原文

  1. $foo = ($bar == $foo)
  2. ? $foo
  3. : $bar;

类型转换

类型转换时,需要在目标类型两边跟上空格:原文

  1. // 正确:
  2. $foo = (string) $bar;
  3. if ( (string) $bar)
  4. // 不正确:
  5. $foo = (string)$bar;

如果可以,请尽量使用类型转换操作来代替三元运算操作:原文

  1. // 正确:
  2. $foo = (bool) $bar;
  3. // 不正确:
  4. $foo = ($bar == TRUE) ? TRUE : FALSE;

当类型转换成整形或布尔型时,请用短格式:原文

  1. // 正确:
  2. $foo = (int) $bar;
  3. $foo = (bool) $bar;
  4. // 不正确:
  5. $foo = (integer) $bar;
  6. $foo = (boolean) $bar;

常量

常量始终使用大写形式:原文

  1. // 正确:
  2. define('MY_CONSTANT', 'my_value');
  3. $a = TRUE;
  4. $b = NULL;
  5. // 不正确:
  6. define('MyConstant', 'my_value');
  7. $a = True;
  8. $b = null;

在作比较运算时应将常量置于的表达式的右端:原文

  1. // 正确:
  2. if ($foo !== FALSE)
  3. // 不正确:
  4. if (FALSE !== $foo)

不过这样的选择确实有一些微小的争议,所以我会来解释其中的依据。如果我们将前面的例子转换为普通的英文来表述,那么其中“正确”的列子则读作:原文

  1. if variable $foo is not exactly FALSE [参考译文:如果变量$foo并不完全就是FALSE]

而“不正确”的例子则会读作:原文

  1. if FALSE is not exactly variable $foo [参考译文:如果FALSE并不不全就是变量$foo]

从左到右的方向读,你会发现放在前面的常量没有任何意义。原文

注释

单行注释

使用//,在你代码的上面一行进行注释,并且要与其后的起始字符相隔一个空格,字母开头的注释要大写。原文

  1. // Correct
  2. //Incorrect
  3. // incorrect
  4. # Incorrect

正则表达式

当编写正则表达式的时候,请使用PCRE的风格而不是POSIX风格。因为PCRE更强大并且更快速。原文

  1. // 正确:
  2. if (preg_match('/abc/i', $str))
  3. // 不正确:
  4. if (eregi('abc', $str))

正则表达串外面应使用单引号而不是使用双引号来包围。使用单引号的字符串因为简单所以更方便。不像使用双引号的字符串那样支持插入变量和反斜线,蔽日 \n 或 \td 等等……原文

  1. // 正确:
  2. preg_match('/abc/', $str);
  3. // 不正确:
  4. preg_match("/abc/", $str);

当使用正则表达式来搜索和体会时,请使用向后引用$n,比起\n这种形式来说。原文

  1. // 正确:
  2. preg_replace('/(\d+) dollar/', '$1 euro', $str);
  3. // 不正确:
  4. preg_replace('/(\d+) dollar/', '\\1 euro', $str);

最后,请注意到用来匹配字符串末端位置的美元符号$允许新行的字符。如果需要,则使用修正符D来解决这个需求。源码

  1. $str = "email@example.com\n";
  2. preg_match('/^.+@.+$/', $str); // TRUE
  3. preg_match('/^.+@.+$/D', $str); // FALSE