腾讯PHP开发规范v1.docx
《腾讯PHP开发规范v1.docx》由会员分享,可在线阅读,更多相关《腾讯PHP开发规范v1.docx(23页珍藏版)》请在冰豆网上搜索。
腾讯PHP开发规范v1
海豹平台开发规v1.0
腾讯科技()
*版本信息&等级
版本
更改日期
更改要点说明
编制
审核
批准
V1.0
2014/12/24
新建
wilsonwsong
V1.1
2014/12/26
修订
rusherding
文档等级:
□■部□公开
1引言
1.1定义及缩略语
缩略词
说明
海豹平台
运维中心提供的研发平台,提供框架、公共基础组件、公共业务组件加速业务的日常研发工作
1.2参考文档
海豹平台WIKI:
wiki.seals.webdev./
1.3目的
本规由编程原则组成,融合并提炼了开发人员长时间积累下来的成熟经验,意在帮助形成良好一致的编程风格。
以达到事半功倍的效果,如果有需要本文档会不定期更新。
1.4适用围
如无特殊说明,以下规则要求完全适用于基于海豹平台框架开发的应用,同时也可大部分适用于部门其他PHP项目。
1.5标准化作用
当一个软件项目尝试着遵守公共一致的标准时,可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。
使新的参与者可以很快的适应环境,防止部分参与者出于节省时间的需要,自创一套风格并养成终生的习惯,导致其它人在阅读时浪费过多的时间和精力。
而且在一致的环境下,也可以减少编码出错的机会。
缺陷是由于每个人的标准不同,所以需要一段时间来适应和改变自己的编码风格,暂时性的降底了工作效率。
从使项目长远健康的发展以及后期更高的团队工作效率来考虑暂时的工作效率降低是值得的,也是必须要经过的一个过程。
标准不是项目成功的关键,但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定的任务。
1)程序员可以了解任何代码,弄清程序的状况
2)新人可以很快的适应环境
3)防止新接触PHP的开发出于节省时间的需要,自创一套风格并养成终生的习惯
4)防止新接触PHP的开发一次次的犯同样的错误
5)在一致的环境下,可以减少犯错的机会
2目录结构规
2.1框架路径
框架引用路径必须采用绝对路径,托管的开发、测试和正式环境必须为:
/data/php/framework
2.2应用目录结构
应用需要严格参考以下目录安排代码位置:
webroot/
index.phpWeb应用入口脚本文件
index-test.php功能测试使用的入口脚本文件
assets/包含公开的资源文件
css/包含CSS文件
images/包含图片文件
themes/包含应用主题
protected/包含受保护的应用文件
modc命令行脚本
modc.batWindows下的命令行脚本
modc.php命令行PHP脚本
mands/包含自定义的'modc'命令
ponents/包含可重用的用户组件
config/包含配置文件
controllers/包含控制器的类文件
SiteController.php默认控制器的类文件
extensions/包含第三方扩展
messages/包含翻译过的消息(i8n相关)
models/包含模型的类文件
runtime/包含临时生成的文件
tests/包含测试脚本
views/包含控制器的视图和布局文件
layouts/包含布局视图文件
main.php所有视图的默认布局
site/包含'site'控制器的视图文件
system/包含系统视图文件
2.2.1配置config
存放应用配置目录,具体参考WIKI人口脚本
2.2.2控制器controllers
存放控制逻辑的类目录,具体参考WIKI控制器
2.2.3模型models
存放模型定义的类目录,具体参考WIKI模型
2.2.4视图views
存放视图文件的目录,具体目录参考WIKI视图
2.2.5国际化messages
存放国际化定义文件的目录
2.2.6组件ponents
存放组件的类目录,具体目录参考WIKI组件
2.2.7命令mands
存放Console命令的类目录,具体目录参考WIKI之Cli使用
2.2.8临时目录runtime
目录权限777,可用于存放临时生成的文件。
2.3路径别名
1)system:
表示平台框架目录,默认为/data/php/framework。
2)webroot:
表示入口脚本文件所在的目录,一般为应用的根目录。
3)application:
表示应用的基础目录,一般为webroot/protected。
4)ext:
表示包含了所有第三方扩展的目录,一般为webroot/protected/extensions。
通过使用Mod:
:
getPathOfAlias(),别名可以被翻译为其相应的路径。
例如:
system.core.web.CController会被翻译为/data/php/framework/core/web/CController。
2.3.1类型导入
使用别名可以很方便的导入类的定义,如导入webroot/protected/ponents/Controller
Mod:
:
import('application.ponents.Controller');
同样可以使用目录导入
Mod:
:
import('application.ponents.*');
3PHP编码规
3.1标签
PHP程序可以使用
php?
>或
=?
>来界定PHP代码,在HTML页面中嵌入纯变量时,可以使用
=?
>这样的形式,不可使用其他的标签变种。
纯PHP类文件,文件最后一个?
>省略。
3.2编码
PHP代码必须只使用不带BOM的UTF-8。
3.3注释
1)单行注释:
在语句结尾用双反斜杠”//“注释
2)多行注释:
多行注视以”/*”或“/**”符号开头,以”*/“符号作为注释结束符。
需要生成文档的注释必须是以“/**”开头,以“*/”结尾。
主流的IDE开发工具(如Eclipse,Zend)会用不同的颜色来区分下面的几种注释。
3.3.1文件注释
/**
*(简述,用在索引列表中)
*
*详细的功能描述(可略)
*
*copyrightCopyright©2014,公司名或作者名
*author${AUTHOR}
*version$Id:
${FILE_NAME},v${VERSION}${TIME}${AUTHOR}Exp$
*
*/
3.3.2类注释
/**
*(概要)
*
*详细的功能描述
*
*property类型$prop属性描述
*
*author${AUTHOR}
*packageapplication.ponents(参见路径别名)
*
*/
3.3.3方法注释
/**
*功能描述
*
*param类型$fields描述
*
*return类型描述
*/
3.3.4属性注释
/**
*var类型$fields描述
*/
3.3.5其它
1)适当的使用HTML标记语言来美化文档。
不管是生成HTML格式还是CHM格式的文档手册,文档工具都是先生成HTML文档页面,所以适当的使用
或标签可以美化文档,方便阅读。
2)public和private方法:
一般情况下,private私有方法不会暴露给其他开发人员,所以private方法的注释一般以“/*”开头,而public方法以“/**”开头。
3.4命名规则
Pascal命名法:
所有单词第一个字母大写,其他字母小写。
Camel命名法(驼峰命名法) :
除了第一个单词,所有单词第一个字母大写,其他字母小写。
采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名。
3.4.1文件
1)类文件的名称和类名一致,如类HelloWorld,相应的文件名为HelloWorld.php
2)配置文件名小写,如config.php
3)嵌套php的view文件使用Camel命名法,第一个字母小写,其他单词的第一个字母大写。
如:
addApp.php
3.4.2类
类命名采用Pascal命名方法,类名应该和文件名相匹配。
3.4.3函数/方法
通常方法一般为一个动作或行为动词,函数/方法的命名采用Camel命名方法
function run()
function runFast()
function getBackground()
尽量用有意义,描述性的词语来命名
用checkForErrors()代替errorCheck(),用dumpDataToFile()代替dataFile()。
有时前缀名是有用的:
is - 含义为问一个关于某样事物的问题。
无论何时,当人们看到is就会知道这是一个问题。
get - 含义为取得一个数值。
set - 含义为设定一个数值
例如:
isHitRetryLimit
部成员函数命名应该是以 “_”开始:
function _isUserTicket ();
3.4.4变量名
1)用有意义的,描述性的词语来命名变量
2)别用缩写。
用name, address, salary等代替 nam, addr, sal 全局变量以”g_” 开头
3)别使用单个字母的变量象i, n, x 等. 使用 index, temp等 ,用于循环迭代的变量例外:
for($i=0;$i3.4.5常量名
量全部使用大写字母和下滑线组成,常量的名称中不允许出现小写字母,可使用分隔符作为下划线。
3.5书写规则
3.5.1文件
1)所有的PHP文件必须使用UnixLF(换行)作为行结束符。
2)所有PHP文件必须以一个空行结束。
3)纯PHP代码的文件关闭标签?
>必须省略
3.5.2行
1)行长度不可有硬限制。
2)行实际长度不应超过80个字符;较长的行应当被拆分成多个不超过80个字符的后续行。
3)空行可以用来改善可读性和区分相关的代码块。
4)一行不应多于一个语句。
3.5.3缩进
每个缩进的单位约定是4个空格的缩进,并且不可使用制表符作为缩进,需每个参与项目的开发人员在编辑器(Eclipse、EditPlus、ZendStudio等)中进行强制设定将TAB转化为4个空格,以防在编写代码时遗忘而造成格式上的不规。
3.5.4控制结构
对于控制结构的样式规则概括如下:
1)控制结构关键词之后必须有一个空格
2)左括号之后不可有空格
3)右括号之前不可有空格
4)在右括号和左花括号之间必须有一个空格
5)代码主体必须有一次缩进
6)右花括号必须主体的下一行
每个结构的主体必须被括在花括号里。
这结构看上去更标准化,并且当加新行的时候可以减少引入错误的可能性。
3.5.4.1if,elseif,else
一个if结构看起来应该像下面这样。
注意括号,空格,花括号的位置;并且else和elseif和前一个主体的右花括号在同一行。
php
if($expr1){
//ifbody
}elseif($expr2){
//elseifbody
}else{
//elsebody;
}
关键词elseif应该替代elseif使用以保持所有的控制关键词像一个单词。
3.5.4.2switch,case
一个switch结构看起来应该像下面这样。
注意括号,空格和花括号。
case语句必须从switch处缩进,并且break关键字(或其他中止关键字)必须和case主体缩进在同级。
如果一个非空的case主体往下落空则必须有一个类似//nobreak的注释。
php
switch($expr){
case0:
echo'Firstcase,withabreak';
break;
case1:
echo'Secondcase,whichfallsthrough';
//nobreak
case2:
case3:
case4:
echo'Thirdcase,returninsteadofbreak';
return;
default:
echo'Defaultcase';
break;
}
3.5.4.3while,dowhile
一个while语句看起来应该像下面这样。
注意括号,空格和花括号的位置。
php
while($expr){
//structurebody
}
同样的,一个dowhile语句看起来应该像下面这样。
注意括号,空格和花括号的位置。
php
do{
//structurebody;
}while($expr);
3.5.4.4for
一个for语句看起来应该像下面这样。
注意括号,空格和花括号的位置。
php
for($i=0;$i<10;$i++){
//forbody
}
3.5.4.5foreach
一个foreach语句看起来应该像下面这样。
注意括号,空格和花括号的位置。
php
foreach($iterableas$key=>$value){
//foreachbody
}
3.5.4.6try,catch
一个trycatch语句看起来应该像下面这样。
注意括号,空格和花括号的位置。
php
try{
//trybody
}catch(FirstExceptionType$e){
//catchbody
}catch(OtherExceptionType$e){
//catchbody
}
3.5.5运算符
1)每个运算符与两边参与运算的值或表达式中间要有一个空格
3.5.6引号
在绝大多数可以使用单引号的场合,禁止使用双引号(性能考虑)。
可以或必须使用单引号的情况包括但不限于下述:
1)字符串为固定值,不包含“\t”等特殊转义字符;
2)数组的固定下标,例如$array['key'];
3)表达式中不需要带入变量,例如$string='test';,而非$string="test$var";
3.5.7关键词
1)PHPkeywords必须使用小写。
2)PHP常量true,false和null必须使用小写。
3.5.8函数
3.5.9类
1)类必须单独一个源文件,并且类名和文件名相同。
2)类的左花括号必须放到下一行,右花括号必须放在类主体的下一行。
3)类文件“?
>”结束标记去掉
php
classFoo
{
[body]
}
4)一个类的extends和implements关键词必须和类名在同一行。
classClassNameextendsParentClassimplementsArrayAccess,Countable
{
//constants,properties,methods
}
5)implements一个列表可以被拆分为多个有一次缩进的后续行。
如果这么做,列表的第一项必须要放在下一行,并且每行必须只有一个接口。
classClassNameextendsParentClassimplements
ArrayAccess,
Countable,
Serializable
{
//constants,properties,methods
}
3.5.10属性
1)所有的属性必须声明可见性。
2)var关键词不可用来声明属性。
3)一个语句不可声明多个属性。
4)属性名称可以使用单个下划线作为前缀来表明保护或私有的可见性。
classClassName
{
public$foo=null;
private$_bar=1;
}
3.5.11方法
1)所有的方法必须声明可见性。
2)方法名不应只使用单个下划线来表明是保护或私有的可见性。
3)方法名在声明之后不可跟随一个空格。
左花括号必须放在下面自成一行,并且右花括号必须放在方法主体的下面自成一行。
左括号后面不可有空格,右括号前面不可有空格。
4)一个方法定义看来应该像下面这样。
注意括号,逗号,空格和花括号:
5)在参数列表中,逗号之前不可有空格,逗号之后必须要有一个空格。
6)方法中有默认值的参数必须放在参数列表的最后面。
classClassName
{
publicfunctionfooBarBaz($arg1,&$arg2,$arg3=[])
{
//methodbody
}
}
7)参数列表可以被分为多个有一次缩进的多个后续行。
如果这么做,列表的第一项必须放在下一行,并且每行必须只放一个参数。
8)当参数列表被分为多行,右括号和左花括号必须夹带一个空格放在一起自成一行。
classClassName
{
publicfunctionaVeryLongMethodName(
ClassTypeHint$arg1,
&$arg2,
array$arg3=[]
){
//methodbody
}
}
9)如果存在,abstract和final声明必须放在可见性声明前面。
10)如果存在,static声明必须跟着可见性声明。
4数据库命名规
4.1命名规
数据库的所有表(Table)、视图(View)、索引(Index)、触发器(Trigger)、函数(Function)和存储过程(StoreProcedure)均应遵循以下命名规。
1)命名统一用大写
2)命名只能由小写字母和数字构成,并且只能是以小写字母打头
3)命名应采用能够准确反映其中文含义的英文单词或英文单词缩写构成,避免出现英文单词和汉语拼音混用的局面
4)命名长度不可以超过25个字符(表名尽量保持在20个字符的长度,然后再其上建立索引、主键、触发器等等的时候,便于加扩展信息)
5)名称的各部分之间以"_"(下划线)连接
6)字段如有相同定义,应该用相同命名
7)命名应避免用关键字,参见附录一《关键字列表》
4.2实体命名
实体(包括库表、视图、函数和索引等)命名结构如下:
prefix[_module]_body[_suffix]
1)为前缀名,表示数据库对象的类型
2)为模块名,按应用模块进行分类,为可选项
3)
为主体名,应该能够清楚地说明对象的含义
4)是后缀名,提供特效的含义,比如在该对象需分表存放时使用,如按月分开存放的表
,为可选项。
4.2.1前缀命名
前缀
数据库对象
t
表(Table)
v
视图(View)
tri
触发器(Trigger)
p
存储过程(Procedure)
tt
临时表(TemporaryTable)
idx
索引(Index)
uk
唯一索引(UniqueIndex)
pk
主键(PrimaryKey)
fk
外键(ForeignKey)
f
函数(Function)
4.2.2后缀命名
后缀
定义
_HIS
历史表
_LOG
流水表
_MAP
对照表
_REL
关系表
_YYYYMMDD
因数据量庞大,需按日分开存放的表
_YYYYMM
因数据量庞大,需按月分开存放的表
4.3字段命名
字段命名结构如下:
prefix_body[_suffix]
1)为前缀名,为必填项,必须为“f”。
2)
为主体名,应该能够清楚地说明对象的含义
3)是后缀名,提供特效的含义,为可选项。
4.3.1后缀命名
以下是一些特别的后缀,代表了这个字段特效的含义。
在其他的情况,应避免使用以下的后缀。
后缀
定义
_DESC
▪参数表的描叙字段
▪一般来讲是VARCHAR(255)
_FLAG
▪只可能是True或False的字段
▪一般来讲是TINYINT
(1)
_ID
▪标识字段,一般来讲是INT(11)
_TYPE
▪类型字段,一般来讲是CHAR
(1)
4.4字段类型
一般来说,在保证正确性的前提下,尽量使用最小的数据类型来存储和表示数据。
小的数据类型一般比大的更快,因为小的数据类型占用的磁盘空间,存和cup缓存都相对小,需要的cpu处理也要相对少;这个原则很重要,但是设计的时候也不要低估需要存储的数据的数据围。
简单的数据类型需要的cup处理周期更少,比如:
对整数的处理比字符串处理更容易,因为字符集和排序规则使得字符串比较复杂化了,两个典型例子是:
使用mysql的嵌数据类型来存储日期和时间而不是字符串,使用整数存储Ip地址而不是字符串。
4.4.1数值类型
1)非万不得已不要使用DOUBLE,不仅仅只是存储长度的问题,同时还会存在精确性的问题。
2)固定精度的小数,也不建议使用DECIMAL,建议乘以固定倍数转换成整数存储,可以大大节省存储空间,且不会带来任何附加维护成本。
3)对于整数的存储,在数据量较大的情况下,建议区分开TINYINT/INT/BIGINT的选择,因为三者所占用的存储空间也有很大的差别,能确定不会使用负数的字段,建议添加unsigned定义。
4.4.2字符类型
1)非万不得已不要使用TEXT数据类型,其处理方式决定了他的性能要低于char或者是varchar类型的处理。
2)定长字段,建议使用CHAR类型,不定长字段尽量使用VARCHAR,且仅仅设定适当的最大长度,而不是非常随意的给一个很大的最大长度限定,因为不同的长度围,MySQL也会有不一样的存储处理。
4.4.3时间类型
1)尽量使用TIMESTAMP类型,因为其存储空间只需要DATETIME类型的一半。
2)对于只需要精确到某一天的数据类型,建议使用DATE类型,因为他的存储空间只需要3个字节,比TIMESTAMP还少。
3)不建议通过INT类型类存储一个unixtimestamp的值,因为这太不直观,会给维护带来不必要的麻烦,同时还不会带来任何好处。
4.4.4ENUM&SET
1)对于状态字段,可以尝试使用ENUM来存放,因为可以极大的降低存储空间。
2)如果是存放可预先定义的属性数据,可以尝试使用SET类型,即使存在多种属性,同样可以游刃有余,同时还可以节省不小的存储空间。
4.4.5LOB类型
强烈反对在数据库中存放LOB类型数据
4.5表结构设计
4.5.1适度冗余
不需要一定遵守式理论,适度的冗余,让Query尽量减少Join
4.5.2尽量使用NOTNULL
尽可能把字段定义成NOTNULL,许多表包含一些字段允许空的字段,即使应用需求