11.3 调试方法

调试模式并不能完全满足我们调试的需要,有时候我们需要手动的输出一些调试信息。除了本身可以借助一些开发工具进行调试外,ThinkPHP还提供了一些内置的调试函数和类库。

变量调试

输出某个变量是开发过程中经常会用到的调试方法,除了使用php内置的var_dump和print_r之外,ThinkPHP框架内置了一个对浏览器友好的var_dump方法,用于输出变量的信息到浏览器查看。
dump 浏览器友好的变量输出
用法dump($var, $echo=true, $label=null, $strict=true)
参数var(必须):要输出的变量,支持所有变量类型
echo(可选):是否直接输出,默认为true,如果为false则返回但不输出
label(可选):变量输出的label标识,默认为空
strict(可选):输出变量类型,默认为true,如果为false则采用print_r输出
返回值如果echo参数为false 则返回要输出的字符串
使用示例:$Blog = D("Blog");
$blog = $Blog->find(3);
dump($blog);
在浏览器输出的结果是:array(12) {
  ["id"]           => string(1) "3"
  ["name"]         => string(0) ""
  ["userId"]       => string(1) "0"
  ["categoryId"]   => string(1) "0"
  ["title"]        => string(4) "test"
  ["content"]      => string(4) "test"
  ["cTime"]        => string(1) "0"
  ["mTime"]        => string(1) "0"
  ["status"]       => string(1) "0"
  ["readCount"]    => string(1) "0"
  ["commentCount"] => string(1) "0"
  ["tags"]         => string(0) ""
}

性能调试

开发过程中,有些时候为了测试性能,经常需要调试某段代码的运行时间或者内存占用开销,系统提供了一些方法可以很方便的获取某个区间的运行时间和内存占用情况。
debug_start 区间调试开始(记录初始时间和内存占用)
用法debug_start($label='')
参数label(可选):区间的label标识,默认为空
返回值
debug_end 区间调试结束(记录区间结束时间和内存占用 并输出结果)
用法debug_end($label='')
参数label(可选):区间的label标识,默认为空,
必须和debug_start的label对应才能输出正确的区间结果
返回值
注意:debug_start和debug_end 方法中的内存占用输出需要环境支持memory_get_usage方法,否则只会显示时间信息。
使用示例:debug_start('run');
$blog = D("Blog");
$blog->select();
debug_end('run');
会输出下面的运行信息:Process run: Times 0.007730s Memories 76 k如果仅仅需要调试时间开销,还可以使用内置的G函数来更方便实现
G 用于记录和统计时间(微秒)
用法G($start,$end='',$dec=4)
参数start(必须):起始位置标识
end(可选):记录结束标记并统计时间
dec(可选):调试时间的统计精度,默认为小数点后4位
返回值如果end为空或者是一个浮点数, 无返回值。
如果end是一个字符串,则返回从start到end位置的使用时间。
使用示例:G('run');
$blog = D("Blog");
$blog->select();
echo G('run','end').'s';
除了上面的 函数外,系统还提供了一个扩展调试类Debug[table][table]
Debug::mark 标记调试位(并记录该位置的时间和内存占用)
用法Debug::mark($name)
参数name(必须):调试标记位的name标识
返回值
Debug::useTime 统计区间标记调试位的使用时间
用法useTime($start,$end,$decimals = 6)
参数start(必须):调试开始位置标识
end(必须):调试结束位置标识
decimals(精度):调试时间的统计精度默认为小数点后6位
返回值区间位置的使用时间(字符串)
Debug::useMemory 统计区间标记调试位的内存占用
用法useMemory($start,$end)
参数start(必须):调试开始位置标识
end(必须):调试结束位置标识
返回值区间位置的内存占用(字符串)
Debug::getMemPeak 统计区间标记调试位的内存占用峰值
用法getMemPeak ($start,$end)
参数start(必须):调试开始位置标识
end(必须):调试结束位置标识
返回值区间位置的内存占用峰值(字符串)
要使用Debug类调试的话,首先需要导入Debug类,Debug类位于扩展目录下面的Library/ORG/Util/Debug.class.php ,所以首先要导入:import('ORG.Util.Debug');
Debug::mark('run');
$blog = D("Blog");
$blog->select();
Debug::mark('end');
echo Debug::useTime('run','end').'s';
echo Debug::useMemory('run','end').'kb';

断点调试

凭借强大的页面Trace信息功能支持,ThinkPHP可以支持断点调试功能。
我们只需要在不同的位置对某个变量进行trace输出即可,例如:$blog = D("Blog");
$vo = $blog->create();
trace('create vo',$vo);
$vo = $blog->find();
trace('find vo',$vo);

错误调试

如果需要我们可以使用下面的方法输出错误信息并中断执行:
halt($msg)  //输出错误信息,并中止执行

模型调试

在模型操作中 ,为了更好的查明错误,经常需要查看下最近使用的SQL语句,我们可以用getLastsql方法来输出上次执行的sql语句。例如:$User = M("User"); // 实例化User对象
$User->find(1);
echo $User->getLastSql();
输出结果是
SELECT * FROM think_user WHERE id = 1
新版每个模型都使用独立的最后SQL记录,互不干扰,但是可以用空模型的getLastSql方法获取全局的最后SQL记录。$User = M("User"); // 实例化User模型
$Info = M("Info"); // 实例化Info模型
$User->find(1);
$Info->find(2);
echo M()->getLastSql();
echo $User->getLastSql();
echo $Info->getLastSql();
输出结果是
SELECT * FROM think_info WHERE id = 2
SELECT * FROM think_user WHERE id = 1
SELECT * FROM think_info WHERE id = 2

getLastSql方法只能获取最后执行的sql记录,如果需要了解更多的SQL日志,可以通过查看当前的页面Trace或者日志文件。

注意:Mongo数据库驱动由于接口的特殊性,不存在执行SQL的概念,因此SQL日志记录功能是额外封装实现的,所以出于性能考虑,只有在开启调试模式的时候才支持使用getLastSql方法获取最后执行的SQL记录。