在本章,你将找到所有的代码小提示和最佳实践,这将使你从 Drupal 开发者中脱颖而出,并帮你摆脱电脑的折磨。

代码规范

Drupal 社区已经达成一致,它的代码基础必须拥有一个标准的外观,从而提高可读性,也使得初学者更容易的学习。社区也鼓励第3方模块的开发者采用这些标准。

行缩进

Drupal 代码缩进使用两个空格,而不是 tab 键。对于大多说编辑器,你都可以设置一个偏好,从而自动的使用 tab 键代替空格,这样你就可以继续使用 Tab 键了 - 如果你习惯使用 tab 键的话。

控制结构

控制结构体是程序中用来控制执行流程的指令,比如条件语句和循环语句。条件语句有 if、else、elseif 和 switch 语句。循环语句有 while、do-while、for 和 foreach。

控制结构体在控制关键字(if、elseif、while、for 等等)和开括号”(”之间应有一个空格,从而将其与函数调用(也使用圆括号)区分开来。”{”应该与关键字位于同一行(而不是自成一行)。

“}”应该自成一行。

不正确的:

if ($a && $b)
{
sink();
}

正确的:

if ($a && $b) {
sink();
}
elseif ($a || $b) {
swim();
}
else {
fly();
}

花括号”{}”一般总是使用的,即便是它们不是必须的时候,为了增强可读性可减少出错的机会。

不正确的:

while ($a < 10)
$a++;

正确的:

while ($a < 10) {
$a++;
}

Switch 语句的格式应该这样:

switch ($a) {
case 1:
red();
break;

case 2:
blue();
break;

default:
green();
}

函数调用

在操作符(=、 <、> 等等)的两边应该各有一个空格,在函数名和函数的开括号”(”之间没有空格。在函数的开括号”(”和它的第一个参数之间也没有空格。中间的函数参数使用逗 号”,”和空格” “分隔的,最后一个参数和闭括号”)”之间没有空格。下面的例子说明了这些要点。

不正确的:

$var=foo ($bar,$baz);

正确的:

$var = foo($bar, $baz);

该规则也存在例外的情况。在一个代码区块中,存在多个相关的赋值语句时,如果能够提高可读性的话,是可以赋值操作符周围插入更多空格的:

$a_value = foo($b);
$another_value = bar();
$third_value = baz();

数组

对于数组,也是使用空格对其每个元素和每个赋值操作符进行分割的。如果数组代码区块跨越了80个字符,那么每个元素都应独立成行。为了提高可读性和维护性,最好都将每个元素独立成行。这样就方便了你来添加或者删除元素。

不正确的:

$fruit['basket'] = array(’apple’=>TRUE, ‘orange’=>FALSE, ‘banana’=>TRUE,
‘peach’=>FALSE);

正确的:

$fruit['basket'] = array(
‘apple’ => TRUE,
‘orange’ => FALSE,
‘banana’ => TRUE,
‘peach’ => FALSE,
);

注意:数组最后一个元素的后面有一个逗号,这不是一个错误,PHP 允许这个语法。放在这里是为了防止犯错,这样开发者就可以方便的在数组列表的最后添加或者删除一个元素。这一规范是允许的,但是不是必须的。

当创建内部的 Drupal 数组时,比如菜单项或者表单定义,总是将每个元素单独成行:

$form['flavors'] = array(
‘#type’ => ’select’,
‘#title’ => t(’Flavors’),
‘#description’ => t(’Choose a flavor.’),
‘#options’ => $flavors,
);

PHP 注释

Drupal 遵循大多数的 Doxygen 注释样式规范。所有的文档区块必须使用下面的语法:

/**
* Documentation here.
*/
除了第一行以外,其它各行在星号(*)前面必须要有一个空格。

注意:Doxygen 是一个能够友好支持 PHP 的文档生成器。它从代码中提取 PHP 注释并生成适合阅读的文档。更多信息,参看 http://www.doxygen.org。

当为一个函数添加说明文档时,文档区块必须紧挨着放在函数前,中间不能存在空行。
Drupal 能够理解下面所列的 Doxygen 构造体;尽管我们能够覆盖其中的大多数,更多关于如何使用它们的信息请参看 Doxygen 的官方站点:

  • @mainpage
  • @file
  • @defgroup
  • @ingroup
  • @addtogroup (as a synonym of @ingroup)
  • @param
  • @return
  • @link
  • @see
  • @{

• @}

遵循这些标准的好处是,你可以使用第3方的 API 模块为你的模块自动生成文档。API 模块实现了 Doxygen 文档生成器规范的一个子集,专门针对 Drupal 代码生成文档进行了优化。访问 http://api.drupal.org 你就可以看到这个模块的一个实际使用的例子,而关于 API 模块的更多信息,参看 http://drupal.org/project/api。

文档例子

让我们从头到脚的看一遍一个模块的轮廓,同时将不同类型的文档高亮显示。

模块的第2行(在 <?php 标签之后)应该包含一个 CVS 标签用来追踪文档的版本号:

// $Id$

当代码被提交到 CVS 以及从 CVS 更新代码(CVS 的代码是最新的)时,这一标签将自动被解析和扩展。之后,它将看起来像下面的这样:

// $Id: comment.module,v 1.523 2007/01/31 15:49:23 dries Exp $

在本章后面你将学到更多关于如何使用 CVS 的知识。

在声明函数以前,你需要花点功夫使用下面的格式写一个关于模块能做什么的文档:

/**
* @file
* One sentence description/summary of what your module does
* goes here.
*
* A paragraph or two in broad strokes about your module and how it behaves.
*/

常量

PHP 常量全部都应该大些,可以使用下划线分隔单词。当定义 PHP 常量时,最好能够解释一下它们是用来做什么的,如下面的代码片段所展示的这样:

/**
* These values should match the IDs in the ‘role’ table.
*/
define(’DRUPAL_ANONYMOUS_RID’, 1);
define(’DRUPAL_AUTHENTICATED_RID’, 2);

函数文档

函数文档应该使用下面的语法:

/**
* Short description.
*
* Longer description goes here.
*
* @param $foo
* A description of what $foo is.
* @param $bar
* A description of what $bar is.
* @return
* A description of what this function will return.
*/
function name_of_function($foo, $bar) {

}

让我们看一个来自于 Drupal 内核 book.module 中的一个例子:

/**
* Format $content as a standalone HTML page. Useful for exporting an HTML
* version of the book.
*
* @param $title
* Plain text title of the page.
* @see theme_book_navigation
* @return
* A standalone HTML page.
* @ingroup themeable
*/
function theme_book_export_html($title, $content) {

}

在前面的例子中有一些新的 Doxygen 结构体

@see 告诉你要引用哪些函数。

@ingroup 将一组相关的函数联系到了一起。在我们的例子中,它创建了一组 themeable(可主题化)函数。你可以创建任何你想要的组名。比较常用的值有:database、themeable 和 search。

提示:你可以在 api.drupal.org 查看一个特定组的所有函数。例如,可主题化(themeable)的函数在 http://api.drupal.org/api/5/group/themeable 全列出来了。

通过程序来检查你代码的样式

在你的 Drupal 根目录下的 scripts 子目录里面,你可以找到一个名为 code-style.pl 的 Perl 脚本,它用来检查你的 Drupal 代码样式。下面讲述如何使用这个脚本。

首先,修改文件的权限从而使它能被执行;否则,你将得到一个”Permission denied(没有相关权限)”的错误。使用 chmod 通过命令行就可以做到这一点,如下所示:

$ cd scripts
$ ls -l
-rw-r-r- 1 mathias mathias 4471 Oct 23 21:10 code-style.pl
$ chmod 744 code-style.pl
$ ls -l
-rwxr-r- 1 mathias mathias 4471 Oct 23 21:10 code-style.pl

Windows 用户不用修改文件的权限,但是在你运行 code-style.pl 以前一定要先把 Perl 安装了。

通过将模块或者其它要评估的文件的位置传递给 code-style.pl,你就可以执行这个脚本了。下面的例子说明了执行脚本的命令:

$ ./code-style.pl ../modules/node/node.module

程序的输出将采用下面的格式:

line number : ‘error’ -> ‘correction’ : content of line

例如,下面的脚本告诉我们,我们需要在 foo.module 的30行中赋值操作符(=)周围添加空格:

foo.module30: ‘=’ -> ‘ = ‘ : $a=1;s

注意:一定要清楚优点和不足。这一脚本做的很不错,但它还没有十全十美,所以你需要细心的评估每一个报告。

使用 egrep 来查找代码

egrep 是一个 Unix 命令,用来在文件中搜索匹配给定正则表达式的位置。不,它不是一个飞鸟(那是 egret 白鹭)。如果你是一个 Windows 用户并且想差试一下下面所列的例子,你可以通过安装一个已编译的版本(参看 http://unxutils.sourceforge.net)或者安装 Cygwin 环境(http://cygwin.com),来使用 egrep。否则,你只能使用操作系统内置的搜索功能而不是 egrep。

当你需要在 Drupal 内核中查找钩子实现时,当查找错误消息生成的位置时,以及其他一些情况时,egrep 都是一个很方便的工具。让我们看一些在 Drupal 根目录下使用 egrep 的例子:

$ egrep -rl ‘hook_load’ .
./modules/forum/forum.module
./modules/poll/poll.module

在前面的情况下,我们从当前目录(.)在 Drupal 文件中递归的搜索(-r)包含 hook_load 的实例,并将匹配实例的文件名打印出来(-l)。现在看下面的例子:

$ egrep -rn ‘hook_load’ .
./modules/forum/forum.module:228: * Implementation of hook_load().
./modules/poll/poll.module:281: * Implementation of hook_load().

这里,我们在我们 Drupal 文件中递归的搜索带有字符串”hook_load” 的实例,并将它们出现的位置以及行号打印出来。我们可以对搜索结果进一步搜索。在接下来的例子中,我们在前面例子的搜索结果集中搜索单词”poll”出现的情况:

$ egrep -rn ‘hook_load’ . | egrep ‘poll’
./modules/poll/poll.module:281: * Implementation of hook_load().

相关文章


没有评论

(*)
(不会公布)