Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4250358
  • 博文数量: 601
  • 博客积分: 15410
  • 博客等级: 上将
  • 技术积分: 6884
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-16 08:11
个人简介

独学而无友,则孤陋而寡闻!

文章分类

全部博文(601)

文章存档

2020年(1)

2018年(4)

2017年(7)

2016年(42)

2015年(25)

2014年(15)

2013年(36)

2012年(46)

2011年(117)

2010年(148)

2009年(82)

2008年(37)

2007年(41)

分类:

2010-08-18 22:37:53

代码指南

出自MoodleDocs

跳转到: ,

此页面尚未开始翻译,或者正在翻译过程中,正需要您来做贡献。 请点击左面导航条最末尾的“English”查看原文,开始翻译。 如果您对翻译流程和Wiki语法不了解,请阅读。

政策的延续和稳定是所有合作项目成功的基石。

编写编码指南是为了给所有的 Moodle 代码提供一个目标。确实有一些比较老的代码并不能满足全部的要求,但它们迟早会被修复。所有新编写的代码都应当尽量遵守这些标准。

目录

[]

通用规则

  1. 所有代码文件应当使用“.php”作为扩展名。
  2. 所有模板文件应当使用“.html”作为扩展名。
  3. 所有文本文件应当使用Unix风格的文本格式(多数的文本编辑器都有这个选项)。
  4. 所有php标记都必须是“完整”标记,如 ……而非如 的短标记。
  5. 所有已经存在的版权声明应当被保留。如果有必要,您可以加入自己的。
  6. 每个文件都应当包含主config.php文件。
  7. 每个文件都应当检查用户的身份是否正确,可以使用函数require_login()和isadmin()、isteacher()、iscreator()或者isstudent()。
  8. 所有访问数据库的操作都应当使用lib/datalib.php中的函数――这样可以兼容更多的数据库服务器。所有的事情都应当是可以用这些函数来完成 的,如果遇到必须要写SQL代码的情况,请记住这些代码应当是跨平台的,且仅仅对您代码中的特定函数(通常在一个lib.php文件中)有效,且代码中用 注释进行明确说明。
  9. 不要建立和使用标准全局变量$CFG、$SESSION、$THEME、$SITE、$COURSE和$USER之外的全局变量。
  10. 所有变量都应当被初始化或者至少在使用前用isset()或empty()等函数进行检测。
  11. 所有字符串都应当可翻译――在“lang/en_utf8”目录中创建新的文本文件,字符串应当使用简洁的英文小写名称,并通过函数get_string()或print_string()来取得。为了保证语言包的向后兼容,绝对不要删除字符串。
  12. 所有帮助文件应当可翻译――在“lang/en_utf8/help”目录中创建文本文件并且通过helpbutton()函数来调用它们。如果要更新帮助文件:
    • 对于小的修改,旧的翻译文件仍然可以继续使用时,可以直接进行修改,但您应当通知 translation AT moodle DOT org。
    • 对于大的修改,应当创建新的文件,新文件的文件名是在原文件名的末尾添加一个数字,并在以后逐渐增加(如filename2.html),这样翻译人员就可以方便地知道文件有了一个新的版本。很显然,新的代码和帮助索引文件都必须修改以指向新版本的文件。
  13. 从浏览器发来的信息(以GET或POST形式发送)都应用了magic_quotes(无论PHP的设置如何),因此直接将它们插入到数据库中是安全的。 所有其它的原始数据(来自文件或数据库的)都必须在插入数据库前使用addslashes()进行预处理。由于在这个问题上人们经常出错,我们编写了一个来介绍如何添加和删除“\”符号。
  14. 非常重要:Moodle中所有的文本,特别是用户提供的文本,都必须使用format_text()函数来输出。这样就可以确保文本已经正确地过滤。在页面上有关于这个问题的更多信息。.
  15. 用户的动作应当用函数记录下来,这些信息会被用于和。

编码风格

我知道,如果您已经习惯了一种编码风格而我却让您改变它是有一点讨厌的,但比较而言,这比日后所有人都需要去搞清混合风格的Moodle代码要好一些。对于人们使用的任何编码风格都有很多支持和反对的意见,但现在正在使用的风格已经存在了,因此请坚持下去。

1. 缩进应当是4个连续的空格。绝对不要使用制表符。

2. 变量名应当是容易理解、有含义的小写英文单词。如果确实需要两个或以上的单词,请把它们连在一起,但要保持名称尽可能短。对于数组对象,请使用复数名称。

     好的: $quiz
好的: $errorstring
好的: $assignments (for an array of objects)
好的: $i (but only in little loops)
     坏的: $Quiz
坏的: $aReallyLongVariableNameWithoutAGoodReason
坏的: $error_string

3. 常量应当总是大写的,并总是以模块的名称作为前缀。单词之间应当用下划线分隔。

     define("FORUM_MODE_FLATOLDEST", 1);

4. 函数名称应当是简单的英文小写单词,且总是以模块名作为前缀以防止模块之间的冲突。单词之间以下划线分隔。变量如果可能应当总有合理的缺省值。注意在函数名和其后的括号之间没有空格。

     function forum_set_display_mode($mode=0) {
global $USER, $CFG;

if ($mode) {
$USER->mode = $mode;
} else if (empty($USER->mode)) {
$USER->mode = $CFG->forum_displaymode;
}
}

5. 语句块必须总是使用大括号(即便是只有一行)。Moodle使用如下风格:

     if ($quiz->attempts) {
if ($numattempts > $quiz->attempts) {
error($strtoomanyattempts, "view.php?id=$cm->id");
}
}

6. 字符串应当尽可能用单引号定义以提高速度。

     $var = 'some text without any variables';
$var = "with special characters like a new line \n";
$var = 'a very, very long string with a '.$single.' variable in it';
$var = "some $text with $many variables $within it";

7. 实用的注释应当尽可能填写,用以解释代码流程和函数与变量的功能。

  • 每个函数和类都应该使用流行的编写,以便自动生成代码文档。
  • 内嵌注释应使用 // 风格,并且整齐布局,使其能融入代码中并和代码对齐。
     /**
* The description should be first, with asterisks laid out exactly
* like this example. If you want to refer to a another function,
* do it like this: {@link clean_param()}. Then, add descriptions
* for each parameter as follows.
*
* @param int $postid The PHP type is followed by the variable name
* @param array $scale The PHP type is followed by the variable name
* @param array $ratings The PHP type is followed by the variable name
* @return mixed
*/
function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
if (!$ratings) {
$ratings = array(); // Initialize the empty array
if ($rates = get_records("forum_ratings", "post", $postid)) {
// Process each rating in turn
foreach ($rates as $rate) {
....etc

8. 换行可以被大方地使用——把东西分散开看起来会比较清楚。一般情况下,在花括号和普通命令之间应当有一个换行符,但在花括号和变量或函数之间可以没有换行符:

     foreach ($objects as $key => $thing) {
process($thing);
}

if ($x == $y) {
$a = $b;
} else if ($x == $z) {
$a = $c;
} else {
$a = $d;
}

9. 当复制一个对象时,要使用php5的clone()函数(否则得到的就仅仅是指向第一个对象的引用)。Moodle会保证这种方法在php4上也能正常工作。

     坏的:   $b = $a;
好的: $b = clone($a);

如果你要复制的并非对象,但包含了对象(如对象数组),那么要使用fullclone()函数。

数据库结构

  1. 每个表格都必须有一个自增的id字段(INT10)作为主键。(参考)
  2. 包含着模块中数据实例的主表格必须和模块同名(譬如widget),并且至少包含如下字段:
    • id - 如上一条所述
    • course - 每个实例所属的课程id
    • name - 每个实例的完整名称
  3. 与模块相关的其它表格的命名规则是:如果它包含的信息是关于“things”的,则它的名字应当是widget_things(注意采用复数形式)。
  4. 表名和字段名都应当避免使用。因此在创建前要仔细检查。
  5. 字段名称应当简短并使用小写,与变量名的规则相同。
  6. 在可能的情况下,包含着对其它表格(如widget)引用的字段应当命名为widgetid。(注意这是个新约定,有一些老的表格并未遵守。)
  7. 布尔字段应当使用小整数类型(如INT4)并存储为0或1,这样就可以在需要时扩展它。
  8. 多数的表格应当有一个timemodified字段(INT10),并用PHP的time()函数取得的当前时间戳来更新它。
  9. 给每个字段定义一个缺省值(并保证它是有意义的)。
  10. 每个表名都必须有前缀($CFG->prefix)。在大多数情况下,您必须自己注意此问题。并且在Postgres中,所有的索引名也必须有前缀。
  11. In order to guarantee follow these simple rules about the use of the AS keyword (only if you need table/colum aliases, of course):
    • 不要将关键字AS用于表格别名
    • 要将关键字AS用于字段别名
  12. 不要创建UNIQUE KEY(限制),用UNIQUE INDEX来代替它。 In the future, if we decide to add referential integrity to Moodle and we need UNIQUE KEYs they will be used, but not now. Please note that the XMLDB editor allows you to specify both XMLDB-only UNIQUE and FOREIGN constraints (and that's good, in order to have the XML well defined) but only underlying INDEXes will be generated.
  13. Those XMLDB-only UNIQUE KEYs (read previous point) only must be defined if such field/fields are going to be the target for some (XMLDB-only too) FOREIGN KEY. Else, create them as simple UNIQUE INDEXes.
  14. 某个版块相关的表格命名时需要遵守以下规则:$CFG->prefix + "block_" + name_of_the_block + anything_else。 例如,$CFG->prefix是“mdl_”,则与“rss_client”版块相关的表格,其名称前缀应当是 “mdl_block_rss_client”(在末尾添加多一些的词不会带来任何问题,如 “mdl_block_rss_client_anothertable”……)。在Moodle 2.0中,这个规则会100%地强制执行,开发者需在此之前做好准备。要了解详情,请参考。
  15. 不要在稳定的部分对数据库进行修改。如果修改的话,用户从一个稳定版本升级到另一个会带来重复的修改。这将会带来严重的错误。
  16. 在SQL查询中查询整数变量时,不要给变量加引号。例如,get_records_select('question', "category=$catid")是对的。get_records_select('question', "category='$catid'") 是错的。这会隐藏变量$catid没有定义的地方的错误。

安全问题(处理表单和URL数据)

  1. 不要依靠“register_globals”。每个变量必须在每个源文件里正确初始化。变量的来源必须显而易见。
  2. 初始化所有的数组和对象,即使它是空的。 $a = array() 或 $obj = new stdClass(); 。
  3. 不要使用optional_variable()函数,使用optional_param()函数来替代它。根据数据类型选择正确的PARAM_XXXX值。
  4. 不要使用require_variable()函数(现在不推荐使用该函数),使用require_param()函数来替代它。根据数据类型选择正确的PARAM_XXXX值。
  5. 早使用data_submitted()时要小心,在使用数据前仍要对其进行清理。
  6. 使用$_GET、$_POST或$_REQUEST。根据您的需要使用更合适的required_param()或optional_param()。
  7. 检查一个动作时,不要使用像if (isset($_GET['something'])) 这样的代码。可以使用诸如:$something = optional_param('something',-1,PARAM_ALPHA),并且根据它取值的范围来判断,如 if ($something>=0) {....
  8. 在所有可能的情况下,把您所有的required_param()、optional_param()和其它的变量初始化一起放在每个文件的开头,这样它们会更容易被找到。
  9. 使用“sesskey”机制保护表单处理函数不被攻击。简单示例:当生成表单的时候,要包含 。在处理表单时,使用 if (!confirm_sesskey()) {error('Bad Session Key');} 检查。
  10. 所有文件名必须用clean_filename()函数“过滤”,但如果已经适当地使用required_param()或optional_param()做了此项工作,则不必如此。
  11. 再把任何从数据库读出的数据写回之前,必须先用处理。一个完整数据对象可以用addslashes_object()一次性完全处理完毕。
  12. 在任何可能的情况下,存入数据库的数据必须来自POST据(也就是来自表单的数据),而不能来自GET数据(也就是来自URL的数据)。
  13. 如果能避免的话,不要使用来自$_SERVER的数据。它会给移植性带来问题。
  14. 在其它地方没有做的情况下,确保所有写入数据库的数据已经用clean_param函数处理过,并且针对数据类型,使用了恰当的PARAM_XXXX。
  15. 如果您编写了自定义的SQL代码,请确保它是正确的。尤其小心在数值周围不要丢失引号,这可能会带来SQL“注入”漏洞。
  16. 每个文件内都要检查它使用的所有数据(尤其是写到数据库的数据)的合法性。不要期盼或依赖其它地方已经检查了。
  17. 被其它文件包含的代码块应当有确切定义的PHP结构(例如类的声明、函数定义等)——直接执行的代码块建议使用变量时不要初始化。
阅读(3740) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~