yii2的核心代码的编码规范


yii2的核心代码的编码规范

https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md

Yii2 在对PSR-2做了一些补充,并且完全兼容PSR-2,所以我个人代码规范遵从这个规范。

1. 总述

yii2的核心代码的编码规范与PSR-2规范完全兼容

  • 文件必须使用 <?php 或 <?= 而不是<?
  • 文件结尾必须有一空行
  • 文件只用不带BOM的UTF-8编码格式
  • 使用4个空格而不是tab分隔
  • 类名风格: StudlyCaps.
  • 类的常量使用全大写加下划线的命名风格
  • 方法和属性命名使用驼峰风格
  • 私有属性命名以下划线为前缀
  • 使用 elseif 而不是 else if.

2. 文件

2.1. PHP 标识符

  • PHP 代码需使用 <?php ?> 或者 <?= 而不能用 <?.
  • 只包含 PHP 的文件不使用结尾符 ?>.
  • 代码行位不适用结尾符.
  • 含有PHP的文件扩展名都使用 .php.

2.2. 编码

PHP 编码必须只使用不带BOM的UTF-8格式

3. 类命名

类命名使用单词首字母大写风格 StudlyCaps. 如 ControllerModel.

4. 类

此处的“类”包含所有的类和接口

  • 类命名使用驼峰风格且单词首字母大写 CamelCase.
  • 花括号从类名的下一行开始
  • 每个类都要有符合phpDoc规范的文档注释块
  • 类声明代码缩进一个tab
  • 每个PHP 文件中只能有一个类
  • 所有的类都需要有命名空间
  • 类名需要符合文件名. 类命名空间需要符合文件目录结构
/**
 * Documentation
 */
class MyClass extends \yii\Object implements MyInterface
{
    // code
}

4.1. 常量

类常量需要使用全大写加下划线。例如:

<?php
class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}

4.2. 属性

  • 公共属性声明需要使用 public 关键词。
  • 公共属性的声明在最开始,在方法声明之前。私有变量也需要在类的顶部声明。但是考虑到可能只会涉及到少数类的方法,私有变量也可以在这些方法前声明。
  • 合适的类属性声明里,公开、保护、私有的优先级依次递增。
  • 为了更易于阅读,属性间不能有空行,属性与方法声明部分间需要有两行空行。
  • 私有变量的命名需要以下划线开始 $_varName.
  • 公共类成员和独立变量需要使用首字母小写的驼峰命名风格,如$camelCase。
  • 使用有描述意义的命名。 $i 和$j 最好不用。

示例:

<?php
class Foo
{
    public $publicProp;
    protected $protectedProp;
    private $_privateProp;
}

4.3. 方法

  • 函数方法使用首字母小写的驼峰命名风格。
  • 命名本身可以说明函数的作用。
  • 类的方法需要使用 privateprotected 和 public 声明可见性. var 不能使用。
  • 花括号需要在函数声明下一行开始。
/**
 * Documentation
 */
class Foo
{
    /**
     * Documentation
     */
    public function bar()
    {
        // code
        return $value;
    }
}

4.4 文件块

@param@var@property 和@return 需要声明类型,例如 booleanintegerstringarray 或者null。可以使用类名,例如 Model 或 ActiveRecord。对于数组类型使用 ClassName[].

4.5 构造函数

  • 使用__construct 而不是php4风格的构造函数名。

5 PHP

5.1 类型

  • 所有的PHP 类型和值都使用小写,包括 truefalsenull 和 array.

改变已有变量的类型被视作非常不好的做法,除非迫不得已不要这样写。

public function save(Transaction $transaction, $argument2 = 100)
{
    $transaction = new Connection; // bad
    $argument2 = 200; // good
}

5.2 字符串

  • 如果字符串内不包括变量或单引号,使用单引号。
$str = 'Like this.';
  • 如果包括单引号,可以是用双引号避免代码问题。

变量替代

$str1 = "Hello $username!";
$str2 = "Hello {$username}!";

下面这种写法不允许。

$str3 = "Hello ${username}!";

字符串连接

在'.'的两边加空格。

$name = 'Yii' . ' Framework';

当字符串很长时使用下述写法。

$sql = "SELECT * "
    . "FROM `post` "
    . "WHERE `id` = 121 ";

5.3 数组

使用PHP 5.4 短数组语法。

数字索引

  • 索引不适用负数。

声明数组时使用以下方法。

$arr = [3, 14, 15, 'Yii', 'Framework'];

当一行中有多个成员时。

$arr = [
    3, 14, 15,
    92, 6, $test,
    'Yii', 'Framework',
];

关联

关联数组用以下声明方式。

$config = [
    'name'  => 'Yii',
    'options' => ['usePHP' => true],
];

5.4 判断语句

  • 判断语句需要在条件插入前后加一个空格。
  • 判定条件内的算子需要用空格隔开。
  • 花括号在同一行开始。
  • 花括号结束需要另起一行。
  • 单行代码也需要用花括号。
if ($event === null) {
    return new Event();
}
if ($event instanceof CoolEvent) {
    return $event->instance();
}
return null;


// the following is NOT allowed:
if (!$model && null === $event)
    throw new Exception('test');

当逻辑合理时,尽量避免在return 后使用 else. 使用警戒条件。

$result = $this->getResult();
if (empty($result)) {
  return true;
} else {
  // process result
}

下述方法更好

$result = $this->getResult();
if (empty($result)) {
  return true;
}

// process result

switch

switch语法使用下述格式:

switch ($this->phpType) {
    case 'string':
        $a = (string) $value;
        break;
    case 'integer':
    case 'int':
        $a = (int) $value;
        break;
    case 'boolean':
        $a = (bool) $value;
        break;
    default:
        $a = null;
}

5.5 调用函数

doIt(2, 3);

doIt(['a' => 'b']);

doIt('a', [
    'a' => 'b',
    'c' => 'd',
]);

5.6 匿名函数 (lambda) 声明

注意 function/use 令牌和左括号之间的空间:

// good
$n = 100;
$sum = array_reduce($numbers, function ($r, $x) use ($n) {
    $this->doMagic();
    $r += $x * $n;
    return $r;
});

// bad
$n = 100;
$mul = array_reduce($numbers, function($r, $x) use($n) {
    $this->doMagic();
    $r *= $x * $n;
    return $r;
});

文档

  • 查阅 phpDoc 了解文档语法
  • 不允许不用文档。
  • 所有的文件都需要在每行开始使用“文档级别”的文档块,在每个类的上头都需要一个“类级别”的文档块。
  • 没有返回值时不需要使用 @return 。
  • 所有yii/base/Object 的继承类中的虚拟属性都需要在文档中加入@property 标签。运行时,这些注释会由对应的getter或setter方法的 @return 或 @param 标签自动生成。当描述与返回标签中不同时,你也可以在getter或setter方法注释中加入@property 标签,以特别地给出文档信息。以下是个示例
  • <?php
      /**
       * Returns the errors for all attribute or a single attribute.
       * @param string $attribute attribute name. Use null to retrieve errors for all attributes.
       * @property array An array of errors for all attributes. Empty array is returned if no error.
       * The result is a two-dimensional array. See [[getErrors()]] for detailed description.
       * @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
       * Note that when returning errors for all attributes, the result is a two-dimensional array, like the following:
       * ...
       */
      public function getErrors($attribute = null)

文件

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * Component is the base class that provides the *property*, *event* and *behavior* features.
 *
 * @include @yii/docs/base-Component.md
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class Component extends \yii\base\Object

函数/ 方法

/**
 * Returns the list of attached event handlers for an event.
 * You may manipulate the returned [[Vector]] object by adding or removing handlers.
 * For example,
 *
 * ~~~
 * $component->getEventHandlers($eventName)->insertAt(0, $eventHandler);
 * ~~~
 *
 * @param string $name the event name
 * @return Vector list of attached event handlers for the event
 * @throws Exception if the event is not defined
 */
public function getEventHandlers($name)
{
    if (!isset($this->_e[$name])) {
        $this->_e[$name] = new Vector;
    }
    $this->ensureBehaviors();
    return $this->_e[$name];
}

Markdown

不难看出,我们在文档中使用Markdown的标记语法。

以下是文档中额外的用于类、方法、属性之间的交叉链接语法。

  • '[[canSetProperty]]会创建一个同类中以 canSetProperty 为名的方法或者属性的链接。
  • '[[Component::canSetProperty]] 会创建一个同命名空间中的Component 类中以 canSetProperty 为名的方法或者属性的链接。
  • '[[yii/base/Component::canSetProperty]] 会创建一个命名空间yii/base.中的Component 类中以 canSetProperty 为名的方法或者属性的链接。
  • '[[Component]] 会创建一个同命名空间中名为 Component 的类的链接。此处也可加入命名空间。

以下是一个使用上述标签的范例

... as displayed in the [[header|header cell]].

“ | ”前的部分是方法、属性或类参考, “ | ”之后是链接标签。

也可以用以下语法链接到指导文档:

[link to guide](guide:file-name.md)[link to guide](guide:file-name.md#subsection)

注释

  • 单行注释需要使用 // 而不是 #。
  • 单行注释需要在对应行。

其他规则

=== [] vs. empty()

尽量用empty()

多个返回点

当内嵌条件判断变得凌乱时,尽早返回。短的时候无所谓。

self vs. static

除以下情况外使用 static

  • 访问常量时必须使用 selfself::MY_CONSTANT
  • 访问私有属性时必须使用 selfself::$_events
  • 递归时可以使用 self 以调用现有实例而不是增加实例。

“不作为”的赋值

用于配置组件禁用部分功能的属性,需要接收逻辑赋值false。 null'', or [] 不能用于此功能。

文件目录/命名空间命名

  • 用小写
  • 代表对象时,用负数 (如 validators)
  • 代表相关功能或特性时,使用单数 (如 web)

常常是最后一把钥匙打开了门