译文地址 https://github.com/yiisoft/yii2/blob/master/docs/internals/core-code-style.md
部分译文:
接下来介绍的这个代码风格被使用在YII2.x核心代码和官方扩展开发上。如果你想拉入一段代码进入内核中,并且考虑使用它。我们并没有强迫您在您的项目上使用此代码风格。您可以选择更合适您的风格。
您可以点击下载 PHP_Codesniffer:https://github.com/yiisoft/yii2-coding-standards
注:camelCase命名分为首字母大写的和首字母小写的两种方式,本文采用StudlyCaps代表首字母大写,camelCase代表首字母小写的。
整体上我们采用PSR-2代码规范,所以一切PSR-2规范也会被应用于我们的项目中
(1)文件必须使用 <?php 或者 <?= 标签。
(2)在文件的尾部应该使用换行符。
(3)PHP代码文件必须使用UTF8无bom编码格式
(4)代码必须使用4空格缩进,而非table键
(5)类名必须使用StudlyCaps(与camelCase区别在于首字母大写)命名方式
(6)类中所有常量必须全部大写字母,采用下划线分割
(7)方法名必须采用camelCase命名方式
(8)变量名必须采用camelCase命名方式
(9)私有变量前面必须以下划线开头
(10)使用elseif 代替else if
2.1、PHP标签
(1)PHP代码必须使用<?php or <?=标签,一定不要采用其他的形式的标签比如<?
(2)当文件中只包含PHP代码的时候,不使用结尾标签 ?>
(3)当然也不要在文件最后一行加空格
(4)如何文件只要包含PHP代码,那么文件后缀都应该是.php
2.2、字符编码
PHP代码必须仅使用UTF8无bom的编码方式
类名必须使用StudlyCaps命名方式。比如,Controller,Model.
这个“类”指的是所有类和接口
(1)所有的代码必须使用4个空格缩进
(2)一个类必须在一个文件中
(3)所有的类必须采用命名空间
(4)类的名字要能够匹配文件名字,类的命名空间必须匹配目录结构
4.1、常量
常量必须采用大写字母用下划线分割的形式,例如:
<?php
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
}4.2、属性
(1)当定义公有类成员的时候需要用public关键词标注
(2)公有的和保护的变量必须被申明在其他任何方法上方,私有的变量也可以在类内部的上方申明,但是也可以在处理他的方法的上方申明(在仅此方法处理他的情况下);
(3)在一个类中的属性声明的顺序应该根据他们的可见性提升(public > protected > private)
(4)当然针对于属性的可见性来说,没有严格的规则
(5)为了更好的代码可读性,两个属性申明之间不应该有空行。并且属性和方法申明之间不应该有两个空行。一个空行应该被加在不同两个逻辑组之间。
(6)私有变量的名称类似于$_varName。
(7)公有的类成员变量应该采用camelCase 首字母小写的命名规则
(8)命名要有意义,不要用类似于 $i 或者 $j 这类无意义的命名
例如
<?php
class Foo
{
public $publicProp1;
public $publicProp2;
protected $protectedProp;
private $_privateProp;
public function someMethod()
{
// ...
}
}4.3、方法
(1)函数和方法应该采用camelCase首字母小写的命名规则
(2)名称应该具有描述意义,说明函数本身的目的。
(3)类的方法经常被定义为public、protected、private修饰符,var不被允许
(4)函数的括号应该另起一行(不类似java的第一括号在函数名称同行)
4.4、文本块
@param, @var, @property 和 @return必须定义类型比如 boolean, integer, string, array 或者null. 你也可以使用类名例如Model 或者 ActiveRecord.
4.5、构造函数
__construct应该被用来替代php4的constructors风格
所有的数据类型和变量均应该小写。包括true,false,null和array。
改变已有的数据类型是不推荐的。除非你必须要写这样的代码。
public function save(Transaction $transaction, $argument2 = 100)
{
$transaction = new Connection; // bad
$argument2 = 200; // good
}如果字符串中不包括变量或单引号时,请使用单引号。
$str = 'Like this.';
如果字符串中有单引号,你可以使用双引号来避免额外的转义。
$str1 = "Hello $username!";
$str2 = "Hello {$username}!";下面的方式是不允许的:
$str3 = "Hello ${username}!";连接字符串时,使用点在空格周围。
$name = 'Yii' . ' FrameWork';
长内容的字符串可以使用下面的方法:
$sql = "SELECT *" . "FROM `post` " . "WHERE `id` = 121 ";
对于数组,我们使用PHP 5.4中的短数组语法。
不要使用负数作为索引。
使用下面的方法来声明数组:
$arr = [3,14,15,'Yii','FrameWork'];
如果有太多的元素时,可单独分行:
$arr = [ 3, 14, 15, 92, 6, $test, 'Yii', 'Framework', ];
使用下面的格式来关联数组:
$config = [ 'name' => 'Yii', 'options' => ['usePHP' => true], ];
控制语句的条件必须有一个独立的空格在前后的插入句。
操作符的括号内应该用空格间隔。
开括号跟控制语句在同一行中。
关括号应该是新起一行。
针对只有一行的语句也使用括号。
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');尽量避免当语句生效时,else在return之后。使用防卫条件。
$result = $this->getResult();
if (empty($result)) {
return true;
} else {
// process result
}要优于:
$result = $this->getResult();
if (empty($result)) {
return true;
}
// process resultswitch使用下面的格式:
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;
} doIt(2, 3);
doIt(['a' => 'b']);
doIt('a', [
'a' => 'b',
'c' => 'd',
]);使用空格在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运行./bulid php-doc时的@return和@param生成。你可以添加一个@property标记到getter或setter,强制给一个属性的信息介绍,在描述不同于刚开始的@return。下面是个例子:
<?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];
}正如你上面例子中看到的,我们使用标签来格式phpDoc的内容。
下面是另外的语法用于类、方法和属性之间在文档中的连接:
① '[[canSetProperty]]'用于创建一个连接在canSetProperty方法或属性在相同的类中。
② '[[Component::canSetProperty]]'用于创建一个连接在相同的命名空间内Component类中canSetProperty方法。
③ '[[yii\base\Component::canSetProperty]]'用于创建一个连接在yii\base命名空间内Component类中canSetProperty方法。
为了给上面提到的连接其它的标签类或方法名,你可以使用下面的语法:
... as displayed in the [[header|header cell]].
当|之后是连接标签时,在|之前的是方法,属性或类相关。
当然也可以连接到引导,使用下面的代码:
[link to guide](guide:file-name.md) [link to guide](guide:file-name.md#subsection)
单行注释可使用//开始,而不是#。
单行注释仅当前行有效。
尽可能使用empty()。
当条件嵌套比较混乱时,尽早返回。如果方法比较简短时,没有关系。
坚持使用static除非出现下面的场景:
① 获取常量必须通过self:self::MY_CONSTANT
② 获取私有属性必须通过self:self::$_events
③ 可以使用self来递归调用当前实现,代替扩展类的实现。
属性可以通过配制组件来接收false,null,''或[]值来不做一些事情。
① 使用小写字母
② 代表对象时,使用复数的形式(如,validators)
③ 代表相关功能或特性时,使用单数的形式(如,web)Yii2-核心框架代码规范