欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Drupal调试之Devel模块使用技巧

shiping1 的头像
drupal开发中,必然会遇到需要代码调试的时候,这时候有人可能会想说用xdebug之类的调试工具,但有的时候你只是想得到一些中间值或者Drupal流程中的一些统计值,抑或是某个函数的输出,使用xdebug显然就显得不那么合适了。在众多调试工具当中,Devel是其中必备的一个,其他各种调试工具,将会在后续文章中一一阐述。

Devel模块作为Drupal的一个调试模块有其天然优势,首先他使用Drupal的机制开发,所以输出信息可以和Drupal很好的整合,另外Devel模块中可以直接调用Drupal的API函数,并且随着社区的贡献,以及Drupal版本的更新,Devel也会因开源的特质越来越贴近开发者的实际需要,另外Devel模块在Drupal性能优化方面也表现不凡,比如SQL查询时间统计、整合xhprof模块的性能优化(xhprof的使用会后续写相关文章讨论),因此Devel模块是Drupaler们的必备工具。

相信每一个Drupaler都知道Devel模块,(Devel模块的的官方地址是 http://www.drupal.org/project/devel),并且在自己的项目中使用他,所以本文不打算流水帐一样讲述所有Devel的特性,而是从中挑出几个或巧妙或不显而易见的一些用法。

1. devel/php (页面)

比如:http://www.example.com/devel/php

这是一个执行PHP代码的Drupal path,对生产服务器来说,这是危险的,但对程序员调试来说是非常有用的。

最简单的,我可以在里面查看任何变量或者函数返回值。

//dpm是devel提供的一个代替var_dump/drupal_set_message的函数,是打印调试信息的利器,请查阅官方介绍
dpm(user_load(1));

但更重要的是我可以用来调试,比如有只有生产服务器才存在无法在本地重现的BUG,我一般就是临时开启Debug模块,然后对大概有问题的函数使用此页面调试,我可以通过函数返回值来定位,如果定位到另外一个函数,就构造输入去那个函数里继续检查输出,这样可以在不打断服务器运行的情况下,做代码跟踪调试,有时可以很快的找到问题所在。

2. devel/switch/登录名 (页面)

比如: http://www.example.com/devel/switch/user-a

有时某些BUG是只有某个用户才会看到的,这是我们需要那个账户的登录信息,但密码显然我们是不容易得到的,这时我们可以用这个功能来切换到这个用户的登录状态,devel还封装了切换用户的block,但更常见的情况是使用这个链接,后面加用户登录名,快速切换到那个账户,以那个用户的身份去观察BUG。

如果你观察这个hook_menu的代码实现,你会发现一个很有意思的核心函数devel_switch_user,他是切换用户功能的主要函数,逻辑也很简单,但这个函数隐藏了一个切换回来的功能,这个功能只能在代码中才能用到,因为原始用户信息是存在静态变量里的。

devel_switch_user('tom'); // 切换成用户tom
 
// 做一些操作
 
devel_switch_user(); // 切换回来

如果没有这个函数,我们会这么写,比较一下就会发现devel模块的写法更简洁。

global $user;
$old_user = $user;
$user = user_load(array('name' => 'tom'));
 
// 做一些操作
$user = $old_user;

3. dd(函数)

有时候当你在调试一些功能时dpm是没有那么好用的,比如调试batch或者没有界面的drupal脚本,我们需要一种新的方式帮助我们调试,dd函数会在这种情况下发挥作用,dd函数的全称是devel_debug, 看代码实现就会发现他将信息输出到一个文件里,之后我们可以通过那个文件查看调试信息,这样我们就可以通过linux的tail命令实时查看调试信息了。

$test = "this is my test";
dd($test, $label = NULL);

dd函数会在网站服务器的临时目录(drupal的文件系统设置或者/tmp目录下)产生一个名为 drupal_debug.txt的文件,可以在服务器上查看相应的输出。

这个命令的缺点在于调试信息的输出文件的位置和名称是写死在代码中的,未来最好可以传参定义或者配置。

4. devel/source?file=Drupal的相对路径 (页面)

这个URL是用来查看源代码的,这个功能在某些情况下也会用到,比如生产服务器出现BUG,你想快速check代码,使用ssh登陆,切换路径,然后来回切换文件查看就不如直接在浏览器里访问方便,前提是你要足够熟悉Drupal的文件结构以及你自己项目的文件结构。当然出于这个目的,这个功能还有点简单,应该可以做一下简单的文件浏览器。

5. SQL调试

Devel在数据库查询的SQL这方面做了一定的努力,比如后台可以开启sql log,并显示在页面最下方,可以按照触发顺序或者执行时间顺序排序显示等等。但是一旦开启了sql log,我们就不得不log所有的sql, 这样查看自己想要看的那个sql就不是那么方便了。

其实devel模块还提供了一个调试方法,就是db_queryd函数,就是把我们常用的db_query后面加一个d,在执行效果不变的前提下,还会print出执行的sql.这个方法比上面的方法简洁了一些,但问题是在页面上print往往不是个好主意,而且你要调试的sql很有可能是被某个第三方API在执行,比如$view->query(),所以我们还要想想有没有别的办法,通过阅读db_query的代码,以及devel的代码,我发现还有一种方法。

global $conf, $queries;
$conf['dev_query'] = 1; //临时开启sql log
 
db_query(); //可以是任意长度的包含sql执行的代码,或者第三方模块的操作数据的API。
$conf['dev_query'] = 0; //关闭sql log
dpm($queries); // 显示sql

$queries是一个全局变量,用于存储sql log, 只有dev_query开启才会记录log,这里假设默认是关闭的,因为我们只想看我们关心的sql。这里没有用variable_get喝variable_set是因为variable_set会触发清缓存操作,性能不好。

如果觉得写起来麻烦,可以考虑封装成函数,比如devel_query_start(); devel_query_end();

最后,Devel模块提供给我们很多查看信息的页面,有时候我们确实需要这些页面查看一些信息,最简单的devel/phpinfo可以查看php的安装信息,我们不需要自己再去创建包含phpinfo()的文件来查看了。Devel模块还提供了一些子模块,还有一些第三方模块与devel模块配合使用,这些话题我将另起一篇文章和大家分享。

希望本文中分享的技巧能对各位Drupaler的工作有所帮助。


声明: 本站所有文章欢迎转载,所有文章未说明,均属于原创,转载均请注明出处。 
本文有效链接: http://www.drupal001.com/2011/12/how-to-use-devel/ 
版权所有: Drupal与高性能网站架构 http://www.drupal001.com


来自 http://www.drupal001.com/2011/12/how-to-use-devel/

普通分类: