1. 为什么要定规范?
编码规范对于程序员而言尤为重要,有以下几个原因:
1) 一个软件的生命周期中,80%的花费在于维护;
2) 几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护;
3) 编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码;
4) 如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品;
为了执行规范,每个软件开发人员必须一致遵守编码规范。
2. 编程惯例
1) 不要使用神奇数字 ,用常量代替这些数字。比如:
if (2 == $studentStatus)
{
// do sth.
}
这个神奇的2 谁也不知道什么意思,如果事先定义:
define(‘STUDENT_STATUS_DROPOUT’, 2); // 退学
if (STUDENT_STATUS_DROPOUT == $studentStatus)
{
// do sth.
}
哦,原来是处理退学学生的。
2) 不可重用变量。
3) 不要改变变量的性质,即定义为字符串的,不要赋值给数组。
4) 方法尽量短,要写精炼的方法。
5) SQL语句中,关键字必须大写,其他小写。比如:
SELECT * FROM tablename WHERE id = 123;
6) 条件中,逻辑判断较多时,请加上(),以便代码清晰,防止运算符优先级问题。
7) 使用require_once。
8) 学会使用注释,比如://* 注释内容 //*/ 和 /* 注释内容 //*/ ,只差一个“/”,但后者才是注释,对需要大段的注释、反注释很有用。
9) 能用单引号的不用双引号。
3. 命名规则
无需看注释就知道当前类或者方法的具体含义。
3.1. 类
类名是一个名词,采用大小写混合的方式,每个单词的首字母大写。尽量使你的类名简洁而富于描述。使用完整单词,避免缩写词(除非该缩写词被更广泛使用,像URL,HTML)。不用下划线。比如:
class Student{},class UserManager {},class ArrayList{} // 好
class user_manager{},class arrayList{} // 不好
3.2. 方法
通常方法都是执行一个动作的,因此方法名是动词+名词,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写,即驼峰命名法(Camel Case )。比如:
// 好的方法名
showStatus(),drawCircle(),addLayoutComponent()
// 不好的方法名
mouseButton() // 名词短语,无法描述方法功能
DrawCircle() // 开头不是小写
add_layout_component() // php几乎所有的方法名,不过我们建议使用驼峰命名法
serverRunning() // 这个方法名表达不清晰,是表达开始服务(更好:startServer()),或者判断服务是否运行了(更好:isServerRunning())
3个基本前缀:
is Resizable(),is Visible(),get Height(),set Height()
3.3. 变量
采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。比如:
$threadInfo,$studentList,$thisIsAnIntegerVariable
3.4. 常量
全部大写,使用下划线分隔。
define(‘THIS_IS_A_CONSTANT’, ‘haha’);
4. 基本语法
1) 每行一个语句,避免在一个语句中给多个变量赋相同的值。比如:
$x = $y = 1;
2) 变量需要初始化。
$x; // NO
$x = array(); // OK
3) 一个空的for、while语句可以没有 {} 块。
4) 使用强制类型转换操作变量,不使用intval,strval和floatval。比如:
$x = 3.569;
$y = (int) $x;
5) 条件判断中,将常量放在运算符的左侧。比如:
define(’STANDARD_ERROR’, 1);
if (STANDARD_ERROR == $errorNum )
{
// ……
}
如果条件中漏了一个“等号“,语法检查器会为你报错。同时能立刻找到数值,而不是在表达式的末端找到它。
6) 一个带返回值的return语句不使用小括号”()”,除非加上()后能使返回处理更为清晰明确。比如:
return $student;
return $myDisk->getSize();
return ($size ? $size : $defaultSize);
7) 三元运算符要简短;如果条件中有运算符,则需要加上()。比如:
$t = (0 <= $x && CONSTANT != $y) ? 1 : -1;
8) 出现在双引号中的变量,加上{} 。比如:
$money = 10;
echo “Tom has {$money} YUAN.”;
5. 格式化
5.1. 行长度
尽量避免一行的长度超过80个字符。用于文档中的例子应该使用更短的行长,长度一般不超过70个字符。
5.2. 换行
else总是换行。
do…while结构中的while无需换行。
try…catch结构中的catch无需换行。
当一个表达式无法容纳在一行内时,可以依据如下一般规则断开之:
1) 在一个逗号后面断开;
2) 在一个操作符前面断开;
3) 宁可选择较高级别(higher-level)的断开,而非较低级别(lower-level)的断开;
4) 新的一行应该与上一行同一级别表达式的开头处对齐;
5) 如果以上规则导致代码混乱或者使代码都堆挤在右边,那就代之以缩进8个空格。
比如:
someMethod(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5); // 好
someMethod1(longExpression1,
someMethod2(longExpression2,
longExpression3)); // 好
longName1 = longName2 * (longName3 + longName4 – longName5)
+ 4 * longname6; // 高级别的断开,好
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longname6; // 不好!
if ((condition1 && condition2)
|| (condition3 && condition4)
|| !(condition5 && condition6))
{
doSomethingAboutIt(); // 看着太挤,不好
}
if ((condition1 && condition2)
|| (condition3 && condition4)
|| !(condition5 && condition6))
{
doSomethingAboutIt(); // 条件缩进更多,层次分明,好
}
if ((condition1 && condition2) || (condition3 && condition4)
|| !(condition5 && condition6))
{
doSomethingAboutIt(); // 好
}
alpha = (booleanExpression) ? beta : gamma;
alpha = (booleanExpression) ? beta
: gamma;
alpha = (booleanExpression)
? beta
: gamma;
5.3. { }
{} 块总是另起一行;if,for,foreach,while即使只有一行,也需要加 {}。比如:
if ($var1)
{
$i = 0;
$j = 1;
}
else if ($var2)
{
$k = 0;
}
else
{
// Do sth.
}
5.4. 空格
“关键字+括号”应该被空格分开,比如if,else,for,foreach,while,catch,switch,case等关键字后面需要加空格。
方法多个参数之间加上空格,比如:getStudentInfo($studentId, $flag)。
数组初始化时,多个值之间加上空格。
+,-,*,/ 等4个字符作为运算符时,需要加上空格,比如:$i + $j。
逻辑运算符两侧需要加上空格,比如:$i > $j。
!(非)后面不加空格。
5.5. 空行
变量和方法之间,方法和方法之间需要加一个空行。
注释上面加一个空行。
5.6. switch
尽量不用switch,一旦使用的话,不要忘记default和break。
5.7. 缩进
使用四个空格长的制表符缩进。
switch内要缩进;case的break要缩进。
6. 注释
6.1. 文档、类
这里,phpDocumentor(http://manual.phpdoc.org/HTMLframesConverter/default/ )提供了有关注释标记的详细说明。
/**
* 这是一个文档、类的注释,以@开头的都是建议使用的。
* 查看{@link User}的设计。
*
* @todo finish the function: getStudentId()
* @copyright hxsd
* @package xx.xx.xx.xx
* @author liyuntian
* @author luoliang
* @version 2.106, 2006/04/21
* @see User
* @since 1.2
* @deprecated deprecated since version 2.0
*/
class Student
{
// Do sth.
}
6.2. 方法
/**
* 这个一个方法注释。
* @access public
* @author liyuntian
* @todo finish the function
* @param integer $studentId 学生ID
* @param integer $flag 学生标记,比如是否显示删除的学生
* @return array 学生信息数组
*/
getStudentInfo($studentId, $flag)
{
return $info;
}
5.1和5.2的注释,均称之为“文档注释”。
6.3. 块注释
/*
* 注释内容
* 注释内容
*/
块注释一般用于源文件开头的版权和版本信息。比如:
/*
* SVN FILE: $Id: bootstrap.php 2042 2009-07-06 05:50:43Z liyuntian $
* Copyright (c) XIAOPHPER(http://www.xiaophper.com ), 2002-2009, All Rights Reserved.
*/
6.4. 单行注释
/** 这是一个单行的文档注释 */
// 这是一个单行注释
单行注释一般用于注释1行文字。如果注释内容超过1行,建议使用文档注释。
function getLittle($v1, $v2)
{
/* if …… */
if ($v1 < v2)
{
return $v1; // v1
}
else
{
return $v2; // v2
}
}
7. 文件部署
7.1. 系统程序
图片放在images下
附件放在attachment下
脚本放在script下
常用方法文件房子includes下
类文件放在includes/class下
语言包放在contents/languages下
模板放在contents/themes下
模板放在contents/caches下
其他文件根据需要新建文件夹放置。
7.2. 库文件
放在非web目录,比如cakephp的库文件,可以放在/data/weblib/cakephp/。
8. 示例文件
/*
* SVN FILE: $Id: bootstrap.php 2042 2009-07-06 05:50:43Z liyuntian $
* Copyright (c) XIAOPHPER(http://www.xiaophper.com ), 2002-2009, All Rights Reserved.
*/
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright (c) XIAOPHPER(http://www.xiaophper.com ), 2002-2009
* @link http://www.hxsd.com/ HXSD
* @package hxsdedu
* @subpackage hxsdedu.model.student
* @since HXSDEDU v 0.8.0.117
* @version $Revision: 2042 $
* @modifiedby $LastChangedBy: liyuntian $
* @lastmodified $Date:: 2009-07-06 13:50:43 +0800 #$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
define(“STUDENT_IS_NOT_EXIST”, -9999); // 学生不存在
define(“STUDENT_STATUS_SIGNUP”, 1); // 登记的学生
define(“STUDENT_STATUS_STUDY”, 1); // 报名上课的学生
define(“STUDENT_STATUS_DROPOUT”, 2); // 退学的学生
Class Student
{
// 学生 ID
private $studentId = 0;
/** 学生名称 */
private $studentName = null;
/**
* 学生信息数组。
* 通过传入学生ID获得。
*/
private $studentInfo = array();
// 系统注册表
$registry = null;
/**
* 构造函数
* @param Object 系统全局变量
*/
public Student($registry)
{
if (is_object($registry))
{
$this->registry = $registry;
}
}
/**
* 由学生ID获取学生信息,并返回。如果不存在,则返回空数组。
*
* @param integer $studentId 学生ID
* @return array 学生信息,
*/
public function getStudent($studentId)
{
/** 查询数据库 */
$this->studentInfo = $this->registry->db->query_one(“SELECT * FROM student WHERE studentId = {$studentId}”);
return $this->studentInfo;
}
/**
* 检查学生是否退学
*
* @param integer $studentId 学生ID
* @return integer 学生不存在,返回-9999,退学返回1,否则返回0
*/
public function isDropout($studentId)
{
// 获取学生信息
$this->getStudent($studentId);
// 不存在此学生
if (empty($this->studentInfo))
{
return STUDENT_IS_NOT_EXIST;
}
else
{
return (STUDENT_STATUS_DROPOUT == $this->studentInfo['status']) ? 1 : 0;
}
}
}
来源:http://www.xiaophper.com/?p=36