Devel模块是个大杂烩,里面包含了许多实用功能,开发者可用它来调试和检查代码的各种细节。) p+ j! q) k* G; L+ j5 {4 f
) }5 d4 j) U; X6 J {! f 你可以从http://drupal.org/project/devel下载该模块(或者使用CVS签出并获得更酷的效果)。安装了devel模块后,一定要启用devel区块。下面是devel区块中一些含义比较模糊的链接,这里给出了明确的解释:: ^, x3 l6 z8 L& U' v+ N, g3 r
% k! x7 u3 R, w" e+ n; K
• Empty cache(清空缓存):这个将执行includes/common.inc中的drupal_flush_all_caches()函数。这与你导航到“管理➤站点配置➤性能”点击“清除缓存数据”的效果是一样的。也就是说,CSS和JavaScript缓存被清空了;新压缩的CSS和JavaScript文件被重新命名,这样就强制客户下载新文件了;主题注册表被重新构建;菜单被重构;node_type表被更新;数据库中的缓存表,用来存储页面、菜单、节点、区块、过滤器、和变量缓存的表,也全被清空了。具体一点,清空的缓存表有cache, cache_block, cache_filter, cache_menu, 和cache_page。第3方模块的自定义缓存表,如果模块实现了hook_flush_caches()(它返回一个数组,里面包含了要被清空的缓存表的名字),那么这些缓存表也被清空。
. J3 x" o, ]+ k; l C& j
3 V, d8 x1 ~2 c+ l• Enable Theme developer(启用主题开发者): 这个链接用来启用主题开发者模块,启用这个模块后,将鼠标指向一个页面元素,就会为你显示出用来生成这个页面元素的模板或主题函数了(参看第8章)。
- @: v/ t9 s; G# o$ K) J0 }& D& f. @
• Function reference(函数引用): 这个函数提供了一列用户函数,这些函数是在这个请求期间使用PHP的get_defined_functions()定义的。点击一个函数的名字,可以查看它的文档。6 s+ y4 O6 O5 K
* c9 }) e- J! m2 v/ w• Hook_elements(): 这个链接使用一种便于阅读的格式来显示hook_elements()调用的结果,在使用表单API时,它会非常有用。5 N! x8 k U- G* l6 P6 K4 ^& C
4 q4 c: B1 s3 E, Z% O8 k• Rebuild menus(重构菜单): 这个调用menu_rebuild(),它将清空并重新构建menu_router表,同时更新menu_links表(参看第4章)。
- Y) `) g* G% f& h3 D F) J5 V \/ L+ A' m0 W6 G
• Reinstall modules(重装模块): 通过运行hook_uninstall()和hook_install()来重新安装一个模块。模式版本号将被设置成最近更新的号码。在重新安装模块以前,对于任何已有的数据库表,如果其对应模块没有实现hook_uninstall(),那么一定要手动的将其清除。/ E4 w$ t& K& z" V, e. d
# d' l& W" @ B2 d/ q9 k; P7 v• Session viewer(会话查看器): 使用这个链接来显示你的$_SESSION变量的内容。' v" N/ t# b+ d a& v
0 K" Z8 t! ?/ }0 A
• Variable editor(变量编辑器):这个链接列出当前存储在variables表中以及你的settings.php文件的$conf数组中的所有变量及它们的值,它还允许你对这些变量进行编辑。一般可以使用variable_get() 和 variable_set()来访问这些变量。
" N' U6 I% b' e2 F" x3 L
6 Q2 Q: @ f( e
9 c, z/ e0 v* ^$ f6 F" t本文摘自:http://zhupou.cn。谢谢! y/ O. p* [( e0 Q" y& w9 _' X, R
% M7 a s, ]7 F' `& J
3 J1 O+ h1 g6 I6 z9 `% D0 a, t
--------------------------------------------------------------------------------------------------------------------------------------' h6 j2 @+ V& C n
下面内容也是相关的,合一吧:. z1 n4 l7 C3 ?/ m8 v1 t5 y
--------------------------------------------------------------------------------------------------------------------------------------9 G. ]9 U( ]% c
?; B) @ W' h. z, f8 d! b* [
8 v$ ?% e6 m5 N! f* X n本drupal教程主要说的是devel模块。
4 A' N H( Y7 e: F1 B s& T) Gdevel模块是开发用的,可以显示数据库查询和页面执行的时间。
1 b9 H* x% ~: G+ q. ?- n/ a3 S6 c6 [+ b' }3 `
14 n! \; O9 `# Y6 }
“Collect query info ”选中以后,收集query的相关信息。+ w8 _: D) h8 D+ G ~/ s
“Display query log”选中以后,是将上面收集query的相关信息展示出来。 Y4 |: {; W& z% T) j+ z# f
所以选择的时候,最好是两个都选中,这样既看到概括收集的信息,也能看到详细的收集信息。
* L# U1 O9 @) c% A0 Q“Sort query log”是query的排序,by source是按照自然结果排序,by duration是按照查询时间的长短排序。; R) ^& ]$ @# b4 T* x8 t+ b
“Slow query highlighting ”是把查询超过输入框数字的(比如本图的5ms)的query红色高亮显示。
v0 \3 B8 }1 y4 { J9 [“Store executed queries”是把执行的查询存贮到表里,有两个表devel_queries和devel_times。 R* p8 @% R; y' j% B2 G: a/ i+ ^
“Sampling interval”目前还没有搞清楚是做什么用的。: o2 K8 n- f9 t H
6 z9 w2 d# O: |! M) t. i2
1 v1 i5 L/ |4 _3 z5 o“Display page timer ”选中是为了显示页面的执行时间在log box。0 `$ I" Z- [, B& [# f3 f8 G
“Display memory usage ”选中是为了显示内存用了多少。
W& @6 c+ z4 f7 i l w) f! }1 Z4 ^0 J“Display redirection page”,如果一个模块执行一个drupal_goto函数的时候,query的信息可能会丢失。选中这个选项后会产生一个中间页,使得查询信息在页面跳转前完成。; H) W0 C- J! C1 Q2 I
“Display form element keys and weights”选中是为了显示内存用了多少。
2 A" O" {, y* B“Error handler ”为你的网站,选择一个错误句柄。Backtrace显示一个有好的错误信息提示,上图中“SMTP library”SMTP库的显示方式。
5 d8 k& e. ]% ]
8 M* _2 @' N5 `注意:' P' S, P2 v6 C: K" _9 |( P
devel的显示是可以控制的,需要到 管理》用户管理》访问控制 中去设置,哪个角色可以看到devel出来的信息,哪个角色不能看到。如下图所示* W- d7 F! A9 B# l" ?
1 K% w9 I# t: c引用一段说明
& Q8 n; X* D: Y3 E% W+ X6 w9 a元测试就是用来将成分分割成不同的独立单元,并决定每一单元的行为是否和期望的一样。尽管Drupal没有一个核心的单元测试API,但它拥有一个相关的学习小组(http://groups.drupal.org/unit-testing),而且它还有一些工具用来帮助开发者创建更高质量的代码。其中最著名的一个就是第3方模块——devel.module。
" N% y: s0 q- }' Q
5 c: I }$ @- M U6 f: KDevel模块
+ E: F- Z2 ^% x3 y9 _. |8 W+ X! ]7 hDevel模块,最初由Moshe Weitzman编写的,它是一个大杂烩,用来帮助开发者调试和检查你的代码各个零碎的方面。6 e" z1 g! p0 X/ ^
) w- n6 Q4 u5 \- P( r6 Y8 Q& p
你可以从http://drupal.org/project/devel获取这个模块(或者使用CVS检出并获得更酷的效果)。安装了devel模块后,一定要启用devel区块。下面是devel区块中比较模糊的一些链接以及其能做什么的列表:6 s+ I( D4 G; f, M$ U
1 k2 X% n% a! T; Q6 l# {$ ]: `• Empty Cache(清空缓存):清空数据库的用来存储页面、菜单、节点、和变量缓存的缓存表。更明确一点就是,这些要被清空的表有cache, cache_filter, cache_menu,和 cache_page。
4 a9 Q* |% |3 S/ Y# J4 k' X3 z' M, o: B" A! A
注意 点击Empty Cache链接不能清空用户定制的缓存表。- o& j3 q/ ~! ~$ H! ^/ ]
) [1 h+ p& b; W
• Function reference(函数引用): 使用PHP的get_defined_functions()得到在当前请求期间所用到用户函数列表。点击一个函数的名字可以查看它的文档。
% x& c' V1 o/ X- b5 {
& o9 p9 f) R8 j! {4 a0 P• Reinstall module(重装模块)s: 通过运行hook_install()来重新安装一个模块。Schema版本号将被设置成最近更新的版本号。在重新安装模块以前,一定要先手工的清理掉任何存在的由该模块生成的数据库表。
: L- z4 |- ~. F
; }8 m# S! g8 k. y+ a• Reset menus(重置菜单):将所有的菜单项重置到它们的默认设置上,并且删除所有的定制菜单项。
3 [# j( x+ }9 I4 h+ s9 A) d: N. ]" R, |+ \- C; b
• Variable viewer(变量查看器):列出当前存储在在variables表中以及你的settings.php文件的$conf数组中的所有变量以及它们的值。一般可以使用variable_get() 和 variable_set()来访问这些变量。+ g' W& n$ o8 _1 z2 z+ T
$ w! p+ B) I4 E; s2 s: O• Session viewer(会话查看器):展示你的$_SESSION变量的内容。& F' ]- _6 J% Y$ X6 ^
' R7 c& |4 K+ R- |$ k! [3 q展示查询
& K3 p' _: I& y4 ~' W4 z6 E打开页面http://example.com/?q=admin/settings/devel,选住“Collect query info”(收集查询信息) 和 “Display query log”(展示查询日志)旁的复选框。/ x4 I8 C0 Q3 P# k! Q) T
# j) R4 n$ ~/ |/ G
一旦你保存了这些设置,你将会看到,在每个页面的最底部,都有一列查询列表,这些查询就是在生成你当前页面所用到的所有的查询!此外,列表还会告诉你生成查询的函数,该查询所耗费的时间,以及查询被调用的次数。- G' F7 P& m: T
( |3 K+ m, |9 ^0 Z2 P4 v在许多有见识的方式中你都可以使用这一信息。例如,如果同一查询在一个页面被调用了40次,那么你就需要检查一下你的代码看是否存在一个坏的循环结构体。如果确实是这样的话,你可以考虑实现一个静态变量,在请求期间,来保存数据库插叙结果。下面的例子说明了这个设计模式的样子(来自taxonomy.module):
3 t: _2 b( a3 v
; W, k2 w5 v; Ffunction taxonomy_get_term($tid) {
" o; b, ]9 |2 M( V7 H# f3 Z6 \/ O8 Dstatic $terms = array();
4 |; T2 w$ f9 b5 f+ Uif (!isset($terms[$tid])) {
+ a' m$ k1 B$ K( U; Q* g' C. u/ P, J$terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid =
* m' k7 a2 S% y% ]4 @/ u- ~%d', $tid));: a/ C* x( {1 X3 f* }0 R1 r6 F
}# F( O; G9 R8 q# \5 w d
return $terms[$tid];4 ^( n/ p9 \/ G: ]
}
3 _. @; O* N9 R& `; v! `7 z5 I: l
9 f. v0 o7 z4 @! k2 m9 @我们创建了一个静态数组来保存结果集,这样如果查询已被执行过了,那么我们就已经有了这个值,这样就可以直接将其返回而不是再次查询数据库了。
* [/ t1 c3 [. P' H; W+ o6 z* h: p) `: {; }/ ^5 W1 T0 N
处理耗费时间的查询6 l i2 f9 ^ {6 i ]2 ^
假定你已经编写了一个名为task(任务)的定制节点模块,而且你使用hook_load()来向节点对象追加关于任务的额外信息。表的schema如下:3 v+ X Z: b7 g8 p
CREATE TABLE task (5 ^* G- S( p% s
nid int,4 W8 x1 e" s" o7 w L7 O, ~
vid int,
3 h7 |# m2 q# R7 B8 Y9 g9 npercent_done int,0 t4 q9 j: y4 X0 d
PRIMARY KEY (nid,vid),, z( l, `/ J U
KEY nid (nid)+ \0 x2 f- c2 w" P
);
. p5 n4 _! h( ]0 n
( X$ g1 U+ ^4 ^( j l$ s/ w在运行了devel.module和查看了查询日志以后,你注意到针对上表的查询拖累你的站点性能!注意超过5毫秒的查询就被默认是缓慢的。
: o1 p; x& s4 @! X! ~& [9 C0 [, G$ n/ C% y6 ^# f& o2 r9 F2 z
毫秒 函数 查询
# s, ]4 c- D3 p# }4 i27.16 task_load SELECT * FROM task WHERE vid = 3( {+ v6 L6 ?# j
' j: _, L$ L) l& v% u3 L/ |0 _
那么为什么这个查询这么耗时呢?如果它是一个使用多表关联的更复杂的查询,那么我们将考虑使用更好的方式来组织数据,但是它是一个非常简单的查询。首先要做的是使用SQL的EXPLAIN语法来查看数据库是怎么解释这个查询的。当你在一个SELECT语句前面追加一个关键字EXPLAIN时,数据库将返回该查询执行计划的相关信息。
i8 k- K1 V5 k! a' q/ W( y" L* ?, x# q# x4 y
EXPLAIN SELECT * FROM task WHERE vid = 3
( O; P3 c0 V4 L2 j+ A |+ TMySQL给出下面的报告:' f6 W/ s- U N: e, y
o1 z0 c0 H9 n* `! Q: M3 \Id select_type table type possible_keys key key_len ref rows Extra# m8 y$ O- E# C: {
1 SIMPLE task system NULL NULL NULL NULL 1
) K1 Z$ W9 A6 K: w4 g" D B3 o, \6 B$ ]: f, E
在这里最重要的一列就是key列,它现在的值为NULL。这告诉我们MySQL在获取结果集时没有使用任何的主键、UNIQUE键、或者索引键;它需要一行一行的查找。所以加快这个查询速度的最好方式是向vid列添加一个UNIQUE键。
& d5 X# F# n2 L% |8 M: v2 t7 g1 d$ x! N% W: V
ALTER TABLE task ADD UNIQUE (vid);
$ I& U& B8 h& B4 X* n; c& ~' k A& c. y2 o$ Z7 |2 e2 G
更多关于MySQL的EXPLAIN信息,参看http://dev.mysql.com/doc/refman/5.0/en/explain.html。* A( A( g8 ^, D" [: h
# N0 a k( Q$ o: R, e+ DDevel模块的其它用途
) @) f( f3 |8 \Devel模块还有一些其它一些方便函数,它们常被忽略却能增加你的开发效率的。8 \ Y& e' {8 x8 S
- s% R7 T8 ]) Z$ L9 n例如,你可以实时的切换当前查看Drupal页面的用户。这对于技术支持和调试其它角色非常有用。为了切换到另一个用户上,导航到URL http://example.com/?q=devel/switch/$uid,其中$uid是你想切换到的用户的ID。另一种方式是,启用“Switch users”(切换用户)区块,它提供了达到相同功能的一组链接。
; N# N7 d, [! N( Q' [ z
2 i3 w# A1 H0 w! D: l6 n9 n你可以使用dsm(), dvm(),dpr(),和 dvr()函数来输出调试信息,这些信息对于其它用户是不可见的。; D: Y0 L8 p/ O0 M
• dsm() 向页面的消息区域输出一个简单变量(比如,一个字符串或者一个整数。)# F5 k6 C& ]8 j
• dvm()向页面的消息区域输出一个var_dump()。对于复杂的变量比如数组或者对象使用这个函数。4 \- t2 z3 Y1 S' L( W \& g3 i
• dpr() 使用一个递归函数在页面顶部输出一个复杂的变量(比如一个数组或者对象)。( b4 W) Y0 ?1 u' S) |& j- h) ?
• dvr()在页面顶部输出一个var_dump()。
5 X. n( O2 [6 _( ^2 J% m
8 ?1 W! P- k$ }, ~这些函数的输出对于没有“access devel information”(“访问devel信息”)权限的用户是不可见的,这对于实时调试非常方便。
I$ V0 k; z' F* V* |5 Q! _2 g# h S# i) d# c
一个使用的例子如下所示:
3 s- v! ?' N O. rdpr(node_load(5)); // Display the data structure of node 5.
3 x; v2 p5 l( C! ? H0 T* wdvr($user); // Display the $user variable.
) p, n4 O2 {, J/ I9 i o+ [0 p本部分摘自:http://www.5iphp.com/drupal-devel ,谢谢!1 h; [# e( f& w5 w. e
+ q' Q; e- {( L( Y d! ?
8 n7 l2 v% f$ {6 |3 g |
|