Drupal专业开发指南 第21章 Drupal开发最佳实践(3)

 
测试和开发代码

                           译者:老葛        ESKALATE 科技公司

 

单元测试就是用来将成分分割成不同的独立单元,并决定每一单元的行为是否和期望的一样。尽管 Drupal没有一个核心的单元测试API,但它拥有一个相关的学习小组(http://groups.drupal.org/unit-testing),而且它还有一些工具用来帮助开发者创建更高质量的代码。其中最著名的一个就是第 3方模块——devel.module。
 
Devel模块
Devel模块,最初由Moshe Weitzman编写的,它是一个大杂烩,用来帮助开发者调试和检查你的代码各个零碎的方面。
 
你可以从 http://drupal.org/project/devel获取这个模块(或者使用CVS检出并获得更酷的效果)。安装了devel模块后,一定要启用devel区块。下面是devel区块中比较模糊的一些链接以及其能做什么的列表:
 
Empty Cache(清空缓存) :清空数据库的用来存储页面、菜单、节点、和变量缓存的缓存表。更明确一点就是,这些要被清空的表有 cache cache_filter cache_menu ,和 cache_page。
 
注意 点击 Empty Cache链接不能清空用户定制的缓存表。
 
Function reference(函数引用) : 使用PHP的 get_defined_functions()得到在当前请求期间所用到用户函数列表。点击一个函数的名字可以查看它的文档。
 
Reinstall module(重装模块)s : 通过运行 hook_install()来重新安装一个模块。 Schema版本号将被设置成最近更新的版本号。在重新安装模块以前,一定要先手工的清理掉任何存在的由该模块生成的数据库表。
 
Reset menus(重置菜单):将所有的菜单项重置到它们的默认设置上,并且删除所有的定制菜单项。
 
Variable viewer(变量查看器):列出当前存储在在variables表中以及你的settings.php文件的$conf数组中的所有变量以及它们的值。一般可以使用variable_get() 和 variable_set()来访问这些变量。
 
Session viewer(会话查看器):展示你的$_SESSION变量的内容。
 
展示查询
打开页面 http://example.com/?q=admin/settings/devel,选住“Collect query info”(收集查询信息) 和 “Display query log”(展示查询日志)旁的复选框。
 
一旦你保存了这些设置,你将会看到,在每个页面的最底部,都有一列查询列表,这些查询就是在生成你当前页面所用到的所有的查询!此外,列表还会告诉你生成查询的函数,该查询所耗费的时间,以及查询被调用的次数。
 
在许多有见识的方式中你都可以使用这一信息。例如,如果同一查询在一个页面被调用了 40次,那么你就需要检查一下你的代码看是否存在一个坏的循环结构体。如果确实是这样的话,你可以考虑实现一个静态变量,在请求期间,来保存数据库插叙结果。下面的例子说明了这个设计模式的样子(来自taxonomy.module):
 
function taxonomy_get_term($tid) {
static $terms = array();
if (!isset($terms[$tid])) {
$terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid =
%d', $tid));
}
return $terms[$tid];
}
 
我们创建了一个静态数组来保存结果集,这样如果查询已被执行过了,那么我们就已经有了这个值,这样就可以直接将其返回而不是再次查询数据库了。
 
处理耗费时间的查询
假定你已经编写了一个名为task(任务)的定制节点模块,而且你使用hook_load()来向节点对象追加关于任务的额外信息。表的schema如下:
CREATE TABLE task (
nid int,
vid int,
percent_done int,
PRIMARY KEY (nid,vid),
KEY nid (nid)
);
 
在运行了devel.module和查看了查询日志以后,你注意到针对上表的查询拖累你的站点性能!注意超过5毫秒的查询就被默认是缓慢的。
 
毫秒          函数              查询
27.16          task_load         SELECT * FROM task WHERE vid = 3
 
那么为什么这个查询这么耗时呢?如果它是一个使用多表关联的更复杂的查询,那么我们将考虑使用更好的方式来组织数据,但是它是一个非常简单的查询。首先要做的是使用SQL的EXPLAIN语法来查看数据库是怎么解释这个查询的。当你在一个SELECT语句前面追加一个关键字EXPLAIN时,数据库将返回该查询执行计划的相关信息。
 
EXPLAIN SELECT * FROM task WHERE vid = 3
MySQL给出下面的报告:
 
Id select_type table  type    possible_keys key  key_len  ref  rows  Extra
1  SIMPLE      task    system      NULL      NULL NULL     NULL  1
 
在这里最重要的一列就是key列,它现在的值为NULL。这告诉我们MySQL在获取结果集时没有使用任何的主键、 UNIQUE键、或者索引键;它需要一行一行的查找。所以加快这个查询速度的最好方式是向vid列添加一个 UNIQUE键。
 
ALTER TABLE task ADD UNIQUE (vid);
 
更多关于MySQL的EXPLAIN信息,参看 http://dev.mysql.com/doc/refman/5.0/en/explain.html
 
Devel模块的其它用途
Devel模块还有一些其它一些方便函数,它们常被忽略却能增加你的开发效率的。
 
例如,你可以实时的切换当前查看 Drupal页面的用户。这对于技术支持和调试其它角色非常有用。为了切换到另一个用户上,导航到URL http://example.com/?q=devel/switch/$uid,其中$uid是你想切换到的用户的ID。另一种方式是,启用“Switch users”(切换用户)区块,它提供了达到相同功能的一组链接。
 
你可以使用dsm(), dvm(),dpr(),和 dvr()函数来输出调试信息,这些信息对于其它用户是不可见的。
• dsm() 向页面的消息区域输出一个简单变量(比如,一个字符串或者一个整数。)
• dvm()向页面的消息区域输出一个var_dump()。对于复杂的变量比如数组或者对象使用这个函数。
• dpr() 使用一个递归函数在页面顶部输出一个复杂的变量(比如一个数组或者对象)。
• dvr()在页面顶部输出一个var_dump()。
 
这些函数的输出对于没有 “access devel information”(“访问devel信息”)权限的用户是不可见的,这对于实时调试非常方便。
 
一个使用的例子如下所示:
dpr(node_load(5)); // Display the data structure of node 5.
dvr($user); // Display the $user variable.
 
模块构造器模块(The Module Builder Module)
http://drupal.org/project/module_builder有一个伟大的模块,它能帮你很容易的构建出你自己的模块的骨架。它向你询问你想要创建的钩子并帮你创建它们,而且带有示例代码。接着你就可以下载这些文本并开始工作了!
 
 
应用剖析和调试
 
下面的 PHP调试器和集成开发环境(IDE)是能够帮你快速找到Drupal瓶颈所在之处的有力工具;他们也在够帮你在你自己的模块内找出低效的算法:
 
Zend Studio IDE: http://www.zend.com/
Komodo IDE: http://www.activestate.com/Products/Komodo/
Eclipse IDE: http://www.eclipse.org/
Xdebug PHP Extension: http://www.xdebug.org/
 
在下面的图中,我们是用了Zend Studio(拥有最漂亮的图形输出,这有争论)的截图,而其它的IDEs也能够生成相似的输出。图21-2展示了一个使用应用剖析器(application profiler)追踪Drupal请求处理,所得到的图形输出。结果显示了每个文件里面的函数所占用的相对时间。在这里,Drupal看起来在includes/bootstrap.inc里花了一般的时间。
图 21-2在Zend IDE中,一个Drupal请求的时间饼图
 
图 21-3 在Zend IDE中,一个Drupal请求的调用追踪( Call trace
 
在图 21-3和21-4中,我们向下钻取,来查看哪些函数在一个请求期间耗费了相对较多的处理器时间。这一特性能方便的帮你决定哪些地方需要多些花工夫进行优化。
 
图 21-4 在Zend IDE中,一个Drupal请求的函数统计
 
 
实时调试是 PHP的特性而不是Drupal的,但是值得在这里讨论一下,这是由于如果你的笔记本上装有一个实时调试器的话,这就标志着你是一个Drupal高手。
 
使用一个 PHP调试器可让你在运行时暂停PHP代码的执行(比如,设置一个断点),并一步一步的检查都发生了些什么。熟悉一个PHP调试器是你作为开发者最应该掌握的一门技术。一帧一帧的追踪代码,就像电影中的慢动作,它是用来调试的非常好的方式,能让你在熟悉一个臭虫的同时逐步掌握Drupal。
 
初学 Drupal的开发着的成人礼是端上一杯沏好的茶,启动调试器,花一些小时一步步的追踪一个标准的Drupal请求的流程,这能够获得关于Drupal如何工作的第一手资料。
 
总结
读完本章后,你应该能够:
• 按照Drupal的代码规范编写代码
• 为你的代码添加注释,这样使用API模块来讲你的注释生成文档
• 使用 egrep来搜索Drupal的代码
• 适用版本控制下载和更新Drupal
• 干净的修改Drupal核心代码
• 使用统一的diff格式生成展示代码修改的补丁
• 使用别人创建的补丁
• 使用devel.module来增强你的开发效率
• 通过开发者的最佳时间来标识Drupal编程高手
 
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值