编码规范

    我们建议其他开发Cake组成部分的人员也应当遵循同样的规范。

    你可以使用CakePHP Code Sniffer 来检查你的代码是否遵循了必要的规范。

    所有代码和注释应当以英文书写。

    添加新特性

    添加新特性,必须伴随相应的测试用例,在提交到代码仓库前,测试用例必须通过。

    缩进

    缩进使用一个制表符。

    所以,缩进应当看起来象这样:

    或者:

    1. $booleanVariable = true;
    2. $stringVariable = 'moose';
    3. if ($booleanVariable) {
    4. echo '布尔值为真';
    5. if ($stringVariable === '驼鹿') {
    6. echo '我们遇到了一只驼鹿';
    7. }
    8. }

    如果你用到多行的函数调用,请使用下面的原则:In cases where you're using a multi-line function call use the following guidelines:

    • 多行函数调用的开始括号必须是位于该行结尾。
    • 多行函数调用中,每行只允许有一个参数。
    • 多行函数调用的结束括号必须位于单独的一行。
      例如,不要使用下面的写法:
    1. $matches = array_intersect_key($this->_listeners,
    2. array_flip(preg_grep($matchPattern,
    3. array_keys($this->_listeners), 0)));

    而是要这样写:

    1. $matches = array_intersect_key(
    2. $this->_listeners,
    3. array_flip(
    4. preg_grep($matchPattern, array_keys($this->_listeners), 0)
    5. )
    6. );

    行的长度

    为了使代码更好的可读性,建议每行保持在大约100个字符的长度。每行不得超过120个字符。

    简而言之:

    • 100个字符是建议性的上限。
    • 120个字符是强制性的上限。

    控制结构是""、"for"、"foreach"、"while"、"switch"这些。下面是使用"if"的一个例子:

    1. if ((expr_1) || (expr_2)) {
    2. // action_1;
    3. } elseif (!(expr_3) && (expr_4)) {
    4. // action_2;
    5. } else {
    6. // default_action;
    7. }
    • 在控制结构中,在第一个括号之前应该有一个空格,在最后一个括号和开始的大括号之间也应该有一个空格。
    • 在控制结构中总是使用大括号,即使他们是不必要的。这会提高代码的可读性,也导致较少的逻辑错误。
    • 开始的大括号应与控制结构放在同一行上。结束的大括号应该新起一行,并且与控制结构应该有相同的缩进级别。包括在大括号中的语句应该新起一行,其代码也应该再缩进一层。
    • 在控制结构中不应该使用内嵌赋值(inline assignment)。
    1. // 错误 = 没有大括号,语句的位置也不对
    2. if (expr) statement;
    3.  
    4. // 错误 = 没有大括号
    5. if (expr)
    6. statement;
    7.  
    8. // 正确
    9. if (expr) {
    10. statement;
    11. }
    12.  
    13. // 错误 = 内嵌赋值
    14. if ($variable = Class::function()) {
    15. statement;
    16. }
    17.  
    18. // 正确
    19. $variable = Class::function();
    20. if ($variable) {
    21. statement;
    22. }

    当整个三元运算可以放在一行之内时,三元运算符是允许的。更长的三元运算就应该分成if else 语句。三元运算符绝对不允许嵌套。括号虽然不必须,但是可以用在三元运算的条件检查之外,使其更清晰:

    1. //很好,简单,易读
    2. $variable = isset($options['variable']) ? $options['variable'] : true;
    3.  
    4. //嵌套的三元运算不好
    5. $variable = isset($options['variable']) ? isset($options['othervar']) ? true : false : false;

    视图文件

    在视图文件(.ctp files)中,开发人员使用关键词控制结构。关键词控制结构在复杂的视图文件中更容易阅读。控制结构可以放在一段大的 PHP 代码段落中,也可以放在单独的 PHP标签中:

    1. <?php
    2. if ($isAdmin):
    3. echo '<p>You are the admin user.</p>';
    4. endif;
    5. ?>
    6. <p>下面也是可以接受的:</p>
    7. <?php if ($isAdmin): ?>
    8. <p>You are the admin user.</p>
    9. <?php endif; ?>

    我们允许 .ctp 文件结尾的 PHP 结束标签(?>)。

    比较

    总是尽可能的严格。如果特意要使用一个不严格的比较,也许应当注释说明是这样,以免混淆为错误。

    要测试一个变量是否为空,建议使用严格检查:

    1. if ($value === null) {
    2. // ...
    1. // 不建议使用
    2. if (null === $this->foo()) {
    3. // ...
    4. }
    5.  
    6. // 推荐使用
    7. if ($this->foo() === null) {
    8. // ...
    9. }

    函数调用

    在函数调用中,函数名和开始的括号之间不允许有空格,在每个参数之间应当有一个空格:

    如上所示,在等号(=)的两边都应该有一个空格。

    方法的定义

    方法定义的例子:

    1. function someFunction($arg1, $arg2 = '') {
    2. if (expr) {
    3. statement;
    4. }
    5. return $var;
    6. }

    带缺省值的参数应该放在函数定义的最后。尽量让你的函数返回一些东西, 至少是true 或者 false ,这样就可以判断函数调用是否成功:

    1. public function connection($dns, $persistent = false) {
    2. if (is_array($dns)) {
    3. $dnsInfo = $dns;
    4. } else {
    5. $dnsInfo = BD::parseDNS($dns);
    6. }
    7.  
    8. if (!($dnsInfo) || !($dnsInfo['phpType'])) {
    9. return $this->addError();
    10. }
    11. return true;
    12. }

    等号两边都有空格。

    类型约束

    接受对象或者数组的参数可以使用类型约束:

    1. /**
    2. * 方法描述。
    3. *
    4. * @param Model $Model 使用的模型。
    5. * @param array $array 数组值。
    6. * @param bool $boolean 布尔值。
    7. */
    8. public function foo(Model $Model, array $array, $boolean) {
    9. }

    这里 $Model 必须是 Model 的实例,$array 必须是数组()。

    注意,如果你要允许 $array 也可以是 ArrayObject 的实例,你就不能用类型约束,因为 array 只接受基本类型:

    1. /**
    2. * 方法描述。
    3. *
    4. * @param array|ArrayObject $array 数组值。
    5. */
    6. public function foo($array) {
    7. }

    方法链接时, 多个方法应当在各自的行上, 并且缩进一个制表符:

    1. $email->from('foo@example.com')
    2. ->to('bar@example.com')
    3. ->subject('A great message')
    4. ->send();

    文档代码块(DocBlocks)

    所有的注释代码块,除了文件中的第一个代码块,之前总是应当有一个空行。

    文件头文档代码块

    所有的 PHP 文件都应当包含一个文件头文档代码块,看起来应当象这样:

    1. <?php
    2. /**
    3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
    4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
    5. *
    6. * Licensed under The MIT License
    7. * For full copyright and license information, please see the LICENSE.txt
    8. * Redistributions of files must retain the above copyright notice.
    9. *
    10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
    11. * @link https://cakephp.org CakePHP(tm) Project
    12. * @since X.Y.Z
    13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
    14. */

    包含的 标签为:

    类文档代码块

    类文档代码块应当象这样:

    1. /**
    2. * 类的简短描述。
    3. *
    4. * 类的详细描述。
    5. * 可使用多行。
    6. *
    7. * @deprecated 3.0.0 在 2.6.0 版本中作废。将在 3.0.0 版本中移除。使用 Bar 代替。
    8. * @see Bar
    9. * @link https://book.cakephp.org/2.0/en/foo.html
    10. */
    11. class Foo {
    12.  
    13. }

    类文档代码块可以包含如下 标签:

    属性文档代码块应当象这样:

    1. /**
    2. * @var string|null 属性的描述。
    3. *
    4. * @deprecated 3.0.0 在 2.5.0 版本中作废。将在 3.0.0 版本中移除。使用 $_bla 代替。
    5. * @see Bar::$_bla
    6. * @link https://book.cakephp.org/2.0/en/foo.html#properties
    7. */
    8. protected $_bar = null;

    属性文档代码块可以包含如下 标签:

    • @deprecated使用 @version <vector> <description> 格式,其中 versiondescription 是必须的。
    • @link
    • @since

    方法/函数文档代码块

    方法和函数文档代码块应当象这样:

    1. /**
    2. *
    3. * 方法的详细描述。
    4. * 可使用多行。
    5. *
    6. * @param string $param2 第一个参数。
    7. * @param array|null $param2 第二个参数。
    8. * @return array cakes 数组。
    9. * @throws Exception 如果出错。
    10. *
    11. * @link https://book.cakephp.org/2.0/en/foo.html#bar
    12. * @deprecated 3.0.0 在 2.5.0 版本中作废。将在 3.0.0 版本中移除。使用 Bar::baz 代替。
    13. * @see Bar::baz
    14. */
    15. public function bar($param1, $param2 = null) {
    16. }

    变量类型

    文档块(DocBlock)中使用的变量类型:

    • 类型
    • 描述
    • mixed
    • 有未定义(或多种)类型的变量。
    • int
    • 整数类型变量(整数)。
    • float
    • 浮点数类型(浮点数)。
    • bool
    • 逻辑类型(true或者false)。
    • string
    • 字符串类型(位于" "或' '中的任何值)。
    • null
    • 空类型。通常与另一种类型一起使用。
    • array
    • 数组类型。
    • object
    • 对象类型。 如果可能应该使用更明确的类名。
    • resource
    • 资源类型(例如由mysql_connect()返回的)。记住, 如果你指定了混合类型, 则需指明是未知, 或者可以是哪些类型。
    • callable
    • 可调用的函数。
      你也可以用竖线(pipe char)组合多个类型:

    对两种以上的类型,通常最好使用 。

    当返回对象本身时,例如为了实现链式方法,应当使用 $this

    1. /**
    2. * Foo function.
    3. *
    4. * @return $this
    5. */
    6. public function foo() {
    7. return $this;

    包括文件

    includerequireinclude_oncerequire_once 没有括号:

    1. // 错误 = 括号
    2. require_once('ClassFileName.php');
    3. require_once ($class);
    4.  
    5. // 正确 = 没有括号
    6. require_once 'ClassFileName.php';
    7. require_once $class;

    当包括类或者库的文件时, 总是只使用require_once 函数。

    PHP 标签

    总是使用长标签(<?php ?>), 而不用短标签(<? ?>)。

    函数

    所有函数名都应为 camelBack 形式:

    1. function longFunctionName() {
    2. }

    类名应为驼峰命名法(CamelCase), 例如:

    1. class ExampleClass {
    2. }

    变量名应当尽可能具有描述性, 但同时越短越好。普通变量应当以小写字母开头,如果含有多个词, 则应当为 camelBack 形式。引用对象变量的变量名应当以大写字母开头,并且与对象所属的类应当以某种方式相关联。例如:

    1. $user = 'John';
    2. $users = array('John', 'Hans', 'Arne');
    3.  
    4. $Dispatcher = new Dispatcher();

    成员的可见范围

    方法和变量应当使用 PHP5 的 private 和 protected 关键字。另外,protected 的方法和变量应当以一个下划线开头(_)。例如:

    1. class A {
    2. protected $_iAmAProtectedVariable;
    3.  
    4. protected function _iAmAProtectedMethod() {
    5. /*...*/
    6. }
    7. }

    私有方法和变量应当以双下划线(__)开头。例如:

    1. class A {
    2. private $__iAmAPrivateVariable;
    3.  
    4. private function __iAmAPrivateMethod() {
    5. /*...*/
    6. }
    7. }

    不过,尽可能避免私有方法或者变量,而使用保护(protected)的(方法或者变量)。后者可以被子类访问或者改变,而私有的(方法或者变量)阻止了扩展或重用。私有也使测试更加困难。

    示例地址

    所有示例用的网址和电子邮箱地址应当使用"example.com"、"example.org"和"example.net",例如:

    文件

    不包含类的文件,其文件名应当小写,并且以下划线分隔单词,例如:

    1. long_file_name.php

    强制转换(Casting)

    做强制转换,我们使用:

    • 类型
    • 描述
    • (bool)
    • 强制转换成布尔类型。
    • (int)
    • 强制转换成整数类型。
    • (float)
    • 强制转换成浮点类型。
    • (string)
    • 强制转换成字符串类型。
    • (array)
    • 强制转换成数组类型。
    • (object)
    • 强制转换成对象类型。
      在适用时,请使用 (int)$var,而不是 intval($var),使用 (float)$var,而不是 。

    常量名称应当大写:

      如果常量名称由多个单词组成的,则应当用下划线分隔,例如: