Discuz! Board

标题: Discuz! 的编码规范 [打印本页]

作者: admin    时间: 2019-10-5 19:54
标题: Discuz! 的编码规范
https://open.dismall.com/?ac=document&page=dev_coderule
前言本规范由编程原则组成,融合并提炼了开发人员长时间积累下来的成熟经验,意在帮助形成良好一致的编程风格。适用范围如无特殊说明,以下规则要求完全适用于Discuz!项目,同时也可大部分适用于COMSENZ旗下其他PHP项目。标准化的重要性和好处当一个软件项目尝试着遵守公共一致的标准时,可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。使新的参与者可以很快的适应环境,防止部分参与者出于节省时间的需要,自创一套风格并养成终生的习惯,导致其它人在阅读时浪费过多的时间和精力。而且在一致的环境下,也可以减少编码出错的机会。缺陷是由于每个人的标准不同,所以需要一段时间来适应和改变自己的编码风格,暂时性的降底了工作效率。从使项目长远健康的发展以及后期更高的团队工作效率来考虑暂时的工作效率降低是值得的,也是必须要经过的一个过程。标准不是项目成功的关键,但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定的任务。PHP编码规范与原则代码标记PHP程序可以使用<?php ?>来界定 PHP 代码,在HTML页面中嵌入纯变量时,可以使用<?php echo $variablename;?>这样的形式。
注意:为了使代码进一步规范化和标准化,从Discuz! X2版本起开始禁用<? ?><?=$variablename?>这种速记形式。注释注释是对于那些容易忘记作用的代码添加简短的介绍性内容。请使用 C 样式的注释“/* */”和标准 C++ 注释“//”。在Discuz!每一个程序文件头部中,应放入相应SVN控制字串,以方便SVN提交时自动更新:
例如:
/** *      [Discuz!] (C)2001-2099 Comsenz Inc. *      This is NOT a freeware, use is subject to license terms * *      $Id$ */程序开发中难免留下一些临时代码和调试代码,此类代码必须添加注释,以免日后遗忘。所有临时性、调试性、试验性的代码,必须添加统一的注释标记“//debug”并后跟完整的注释信息,这样可以方便在程序发布和最终调试前批量检查程序中是否还存在有疑问的代码。例如:$num = 1;$flag = TRUE;         //debug 这里不能确定是否需要对$flag进行赋值if(empty($flag)) {        //Statements}书写规则缩进每个缩进的单位约定是一个TAB(4个空白字符宽度),需每个参与项目的开发人员在编辑器(UltraEdit、EditPlus、Zend Studio等)中进行强制设定,以防在编写代码时遗忘而造成格式上的不规范。本缩进规范适用于PHP、JavaScript中的函数、类、逻辑结构、循环等。大括号{}、if和switch
以下是符合上述规范的例子:
if($condition) {        switch($var) {                case 1:         echo ‘var is 1’; break;                case 2:         echo ‘var is 2’; break;                default:         echo ‘var is neither 1 or 2’; break;        }} else {        switch($str) {                case ‘abc’:                        $result = ‘abc’;                        break;                default:                        $result = ‘unknown’;                        break;        }}运算符、小括号、空格、关键词和函数根据上述原则,以下举例说明正确的书写格式:$result = (($a + 1) * 3 / 2 + $num)).’Test’;$condition ? func1($var) : func2($var);$condition ? $long_statement : $another_long_statement;if($flag) {        //Statements        //More than 15 lines}showmessage(‘请使用 restore.php 工具恢复数据。’);函数定义例如,符合标准的定义:function authcode($string, $operation, $key = '') {        if($flag) {                //Statement        }        //函数体}不符合标准的定义:function authcode($string,$operation,$key = ''){        //函数体}引号PHP中单引号和双引号具有不同的含义,最大的几项区别如下:UPDATE cdb_members SET adminid=’1’ WHERE username=’$admin’ AND adminid=’2’;所有数据在插入数据库之前,均需要进行addslashes()处理,以免特殊字符未经转义在插入数据库的时候出现错误。Discuz!中所有通过 GET, POST, FILE,取得的变量默认情况下已经使用了addslashes()进行了转义,不必重复进行。如果数据处理必要(例如用于直接显示),可以使用 stripslashes() 恢复,但数据在插入数据库之前必须再次进行转义。缓存文件中,一般对缓存数据的值采用 addcslashes($string, '\'\\')进行转义。Discuz!语言问题在功能设计阶段,当需要使用中文或者给出用户中文提示的时候可以直接在程序中插入简体中文文字,待程序整理和测试阶段由专人进行语言分离工作;功能说明性语言、短语一般不使用“。”或者其他标点符号作为结束,文字中的标点符号,应使用全角。但注意:由于中英文模板与语言包问题,功能说明性的语言中,冒号使用半角”:”,而不使用全角;提示信息(用showmessage()和cpmsg()显示的)和使用技巧(如后台管理界面中的tips)等大篇幅文字中,当中的标点符号应当遵循中文语法规则,以使用全角中文标点为主,结尾应当加入全角句号。尽管程序语言包是在最后整理阶段才进行提取,但程序中直接写出的中文内容,也应充分保证书面语的特征:语言通顺、简洁、得体、无歧义。应彻底杜绝认为直接写提示语言是临时性操作的想法,反复推敲,并总结之前提示语言的特征规范,加以应用。良好的语言文字表达能力,是每个优秀程序员必须具备的基本素质之一。命名原则命名是程序规划的核心。古人相信只要知道一个人真正的名字就会获得凌驾于那个人之上的不可思议的力量。只要你给事物想到正确的名字,就会给你以及后来的人带来比代码更强的力量。名字就是事物在它所处的生态环境中一个长久而深远的结果。总的来说,只有了解系统的程序员才能为系统取出最合适的名字。如果所有的命名都与其自然相适合,则关系清晰,含义可以推导得出,一般人的推想也能在意料之中。就一般约定而言,类、函数和变量的名字应该总是能够描述让代码阅读者能够容易的知道这些代码的作用。形式越简单、越有规则,就越容易让人感知和理解。应该避免使用模棱两可,晦涩不标准的命名。
变量、对象、函数名常量变量的初始化与逻辑检查
任何变量在进行累加、直接显示或存储前必需进行初使化,例如:
$number = 0;                         //数值型初始化$string = ‘’;                 //字符串初始化$array = array();         //数组初始化empty()和isset()的区别为:如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。安全性PHP中的变量不并不像C语言那样需要事先声明,解释器会在第一次使用时自动创建他们,同样类型也不需要指定,解释器会根据上下文环境自动确定。从开发人员的角度来看,这无疑是一种极其方便的处理方法。一个变量被创建了,就可以在程序中的任何地方使用。这导致的结果就是开发人员工经常不注意初始化变量。因此,为了提高程序的安全性,我们不能相信任何没有明确定义的变量。所有的变量在定义使用前要初使化以防止恶意构造提交的变量覆盖程序中使用的变量。兼容性代码重用代码的有效重用可以减少效率的损失与资源的浪费。在开发软件项目时为了避免重复劳动和浪费时间。开发人员应尽量提高现有代码的重用率,同时将更多的精力用在新技术的应用和新功能的创新开发上面。需要强调的是,本部分虽然篇幅较短,但却是十分需要经验,并将花费开发者大量时间和精力去进行优化的部分,任何产品开发者必须时刻清楚和理解代码重用的重要性和必要性,切实在增强产品效率、逻辑性和可读性上下功夫,这是一名优秀软件开发者所必须具备的基本素质。其他细节问题包含调用if(!defined('IN_DISCUZ')) {        exit('Access Denied');}错误报告级别数据库设计字段表和字段命名表和字段的命名以前面《4.4命名原则》的约定为基本准则。所有数据表名称,只要其名称是可数名词,则必须以复数方式命名,例如:cdb_members(用户表)、cdb_posts(帖子表);存储多项内容的字段,或代表数量的字段,也应当以复数方式命名,例如:params(parameters,自定义Discuz!代码的参数个数)、views(查看次数)、replies(回复次数)。当几个表间的字段有关连时,要注意表与表之间关联字段命名的统一,如cdb_threads表中的tid与cdb_posts表中的tid。代表id自增量的字段,通常用以下几种形式:
所有与表、字段相关的命名,请务必大量参考Discuz!现有字段的命名方式,以保证命名的系统性和统一性。
字段结构
字段类型存储空间(b)UNSIGNED取值范围
tinyint1-128~127
0~255
smallint2-32768~32767
0~65535
mediumint3-8388608~8388607
0~16777215
int4-2147483648~2147483647
0~4294967295
bigint8-9223372036854775808~9223372036854775807
0~18446744073709551615
SQL语句如下的语句范例,是符合规范的:$query = $db->query("SELECT s.*, m.* FROM {$tablepre}sessions s, {$tablepre}members m WHERE m.uid=s.uid AND s.sid='$sid');性能与效率定长与变长表包含任何varchar、text等变长字段的数据表,即为变长表,反之则为定长表。
进行表结构设计时,应当做到恰到好处,反复推敲,从而实现最优的数据存储体系。
运算与检索结构优化与索引优化索引能加快查询速度,而索引优化和查询优化是相辅相成的,既可以依据查询对索引进行优化,也可以依据现有索引对查询进行优化,这取决于修改查询或索引,哪个对现有产品架构和效率的影响最小。索引优化与查询优化是多年经验积累的结晶,在此无法详述,但仍然给出几条最基本的准则。首先,根据产品的实际运行和被访问情况,找出哪些SQL语句是最常被执行的。最常被执行和最常出现在程序中是完全不同的概念。最常被执行的SQL语句,又可被划分为对大表(数据条目多的)和对小表(数据条目少的)的操作。无论大表或小表,有可分为读(SELECT)多、写(UPDATE/INSERT)多或读写都多的操作。对常被执行的SQL语句而言,对大表操作需要尤其注意:而小表就相对简单,加入符合查询要求的特定索引,通常效果比较明显。同时,定长化小表也有益于效率和负载能力的提高。字段比较少的小定长表,甚至可以不需要索引。其次,看SQL语句的条件和排序字段是否动态性很高(即根据不同功能开关或属性,SQL查询条件和排序字段的变化很大的情况),动态性过高的SQL语句是无法通过索引进行优化的。惟一的办法只有将数据缓存起来,定期更新,适用于结果对实效性要求不高的场合。MySQL索引,常用的有PRIMARY KEY、INDEX、UNIQUE几种,详情请查阅MySQL文档。通常,在单表数据值不重复的情况下,PRIMARY KEY和UNIQUE索引比INDEX更快,请酌情使用。事实上,索引是将条件查询、排序的读操作资源消耗,分布到了写操作中,索引越多,耗费磁盘空间越大,写操作越慢。因此,索引决不能盲目添加。对字段索引与否,最根本的出发点,依次仍然是SQL语句执行的概率、表的大小和写操作的频繁程度。查询优化MySQL中并没有提供针对查询条件的优化功能,因此需要开发者在程序中对查询条件的先后顺序人工进行优化。例如如下的SQL语句:SELECT * FROM table WHERE a>’0’ AND b<’1’ ORDER BY c LIMIT 10;事实上无论a>’0’还是b<’1’哪个条件在前,得到的结果都是一样的,但查询速度就大不相同,尤其在对大表进行操作时。开发者需要牢记这个原则:最先出现的条件,一定是过滤和排除掉更多结果的条件;第二出现的次之;以此类推。因而,表中不同字段的值的分布,对查询速度有着很大影响。而ORDER BY中的条件,只与索引有关,与条件顺序无关。除了条件顺序优化以外,针对固定或相对固定的SQL查询语句,还可以通过对索引结构进行优化,进而实现相当高的查询速度。原则是:在大多数情况下,根据WHERE条件的先后顺序和ORDER BY的排序字段的先后顺序而建立的联合索引,就是与这条SQL语句匹配的最优索引结构。尽管,事实的产品中不能只考虑一条SQL语句,也不能不考虑空间占用而建立太多的索引。同样以上面的SQL语句为例,最优的当table表的记录达到百万甚至千万级后,可以明显的看到索引优化带来的速度提升。依据上面条件优化和索引优化的两个原则,当table表的值为如下方案时,可以得出最优的条件顺序方案:
字段a字段b字段c
1711
2810
3913
最优条件:b<’1’ AND a>’0’
最优索引:INDEX abc (b, a, c) 原因:b<’1’作为第一条件可以先过滤掉75%的结果。如果以a>’0’作为第一条件,则只能先过滤掉25%的结果
注意:
  • 字段c由于未出现于条件中,故条件顺序优化与其无关
  • 最优索引由最优条件顺序得来,而非由例子中的SQL语句得来
  • 索引并非修改数据存储的物理顺序,而是通过对应特定偏移量的物理数据而实现的虚拟指针
EXPLAIN语句是检测索引和查询能否良好匹配的简便方法。在phpMyAdmin或其他MySQL客户端中运行EXPLAIN+查询语句,例如EXPLAIN SELECT * FROM table WHERE a>’0’ AND b<’1’ ORDER BY c;这种形式,即使得开发者无需模拟上百万条数据,也可以验证索引是否合理,相关细节请参考MySQL说明。值得提出的是,Using filesort是最不应当出现的情况,如果EXPLAIN得出此结果,说明数据库为这个查询专门建立了一个用以缓存结果的临时表文件,并在查询结束后删除。众所周知,硬盘I/O速度始终是计算机存储的瓶颈,因此,查询中应当尽全力避免高执行频率的SQL语句使用filesort。尽管,开发者永远都不可能保证产品中的全部SQL语句都不会使用filesort。限于篇幅,本文档远远没有涵盖数据库优化的方方面面,例如:联合索引与普通索引的可重用性、JOIN连接的索引设计、MEMORY/HEAP表等。数据库优化实际上就是在很多因素和利弊间不断权衡、修改,惟有在成功与失败经验中反复推敲才能得出的经验,这种经验往往就是最难能可贵和价值连城的。兼容性问题模板设计代码标记HTML代码标记一律采用小写字母形式,杜绝任何使用大写字母的方式模板中所有的逻辑体,如{if}、{loop}等,必须前后使用HTML注释(),即类似的形式。事实上,Discuz!模板编译器是支持不加HTML注释的逻辑体写法的,但加入注释可以使得模板可读性更好,同时方便用户使用DreamWeaver或FrontPage等对模板进行修改。在HTML标记中使用的逻辑体无需使用HTML注释(),即<input type=”text”{if xxx} value=”1”{/if} />书写规则HTML所有HTML标记参数赋值需使用双引号包含,例如,应当使用<input type=”text” name=”test” value=”ok” />,而绝对不能使用<input type=text name=test value=ok />。在任何情况下,产品中的模板文件必须采用手写HTML代码的方式,而绝对不能使用DreamWeaver、FrontPage等自动网页制作工具进行撰写或修改。非成对标记必须以“/>”结尾,如
、<input …/>,<input /> 标记的属性必须按照以下顺序书写:<input type="" name="" id="" class="" … />变量模板中使用的变量,依据作用和出现位置不同,分为几种方式:偶尔的,开发者需要使用{}将变量括起来,以免出现模板编译错误,可能的情况如下:语言元素Discuz!模板编译器可以解析对应于./templates/default/templates.lang.php(以默认模板为例)的语言元素。在模板中调用相应语言元素的代码为{lang item},其中item为在templates.lang.php中定义的语言元素名。缩进在Discuz!的*模板文件中,由于具备逻辑结构,故不考虑任何HTML本身的缩进,所有缩进均意为着逻辑上的缩进结构。缩进采用TAB方式,不使用空格作为缩进符号,仅需适当断行即可。例如:<!--{loop $threadlist $thread}-->        <table cellspacing=”0” cellspadding=”0” border=”0”>        <tr><td>$thread[message]</tr></td>        </table><!--{/loop}-->文件与目录文件命名所有包含PHP代码的程序文件或半程序文件,应以小写.php作为扩展名,而不要使用.phtml、.php3、.inc、.class等作为扩展名。普通程序能够被URL直接调用的程序,例如home.php、index.php、forum.php,直接使用程序名+.php的方式命名函数库和类库程序分别以小写function_xxxx.php和class_xxxx.php的格式命名书写。函数库和类库程序只能被其他程序引用,而不能独立运行。其中不能包含任何流程性的、不属于任何函数或类的程序代码。流程性程序以小写.inc.php作为扩展名。只能被其他程序引用,而不能独立运行。其中不能包含任何函数或类代码的程序代码。模板源文件以小写作为扩展名。模板源文件按照Discuz!模板编码规则进行编写,不是可以执行的程序,而只能被Discuz!模板编译器所解析,放置于./templates/default或./templates下的其他模板目录下。模板目标文件模板文件被编译后自动生成的目标程序,以小写.tpl.php作为扩展名,存放于./data/template目录下。语言包文件缓存文件此类文件为系统自动生成,以cache_xxx.php、usergroup_xxx.php、style_xxx.php等类似形式命名,存放于./data/cache目录下。目录命名空目录索引





欢迎光临 Discuz! Board (http://ankix.shawsen.com/) Powered by Discuz! X3.2