原文地址: https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md
1. 总述
- 文件必须使用
<?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
. 如 Controller
, Model
.
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. 方法
- 函数方法使用首字母小写的驼峰命名风格。
- 命名本身可以说明函数的作用。
- 类的方法需要使用
private
,protected
和public
声明可见性.var
不能使用。 - 花括号需要在函数声明下一行开始。
/**
* Documentation
*/
class Foo
{
/**
* Documentation
*/
public function bar()
{
// code
return $value;
}
}
4.4 文件块
@param
, @var
, @property
和@return
需要声明类型,例如 boolean
, integer
, string
, array
或者null
。可以使用类名,例如 Model
或 ActiveRecord
。对于数组类型使用 ClassName[]
.
4.5 构造函数
使用__construct
而不是php4风格的构造函数名。
5 PHP
5.1 类型
- 所有的PHP 类型和值都使用小写,包括
true
,false
,null
和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
- 访问常量时必须使用
self
:self::MY_CONSTANT
- 访问私有属性时必须使用
self
:self::$_events
- 递归时可以使用
self
以调用现有实例而不是增加实例。
“不作为”的赋值
用于配置组件禁用部分功能的属性,需要接收逻辑赋值false。 null
, ''
, or []
不能用于此功能。
文件目录/命名空间命名
- 用小写
- 代表对象时,用负数 (如 validators)
- 代表相关功能或特性时,使用单数 (如 web)