PHP XDEBUG 扩展 | 文档

Xdebug 内置 profiler 可以找到脚本中的瓶颈,可以用诸如 KCacheGrind 或者 WinCacheGrind 这样的外部工具来让其方便人类阅读。


说明

xdebug 的 profiler 是一个强大的工具,它能分析 PHP 代码,探测瓶颈,或者通常意义上来说查看哪部分代码运行缓慢以及可以提升速度。从 Xdebug 2.6 起,profiler 也能收集使用了多少内存和哪个函数或方法加剧了内存使用的信息。

Xdebug 分析器输出一种兼容 cachegrind 文件格式的分析信息这允许你能使用出色的 KCacheGrind 工具(Linux,KDE)来分析你的 profiling 数据。在 Linux 可以使用你最喜欢的包管理器安装 KCacheGrind。

在 Windows 系统上,有预编译的 QCacheGrind 二进制程序(QCacheGrind 是没有 KDE 绑定的 KCacheGrind)。

在 Mac OSX 系统上,这里也有怎样安装 QCacheGrind 的说明

Windows 用户可以选择性的使用 WinCacheGrind。它的功能不同于 KCacheGrind,所以 这个页面的 KCacheGrind 使用文档章节不适用于这个程序。WinCacheGrind 目前不支持 Xdebug 2.3 引入的 cachegrind 格式的文件和函数压缩。

这也有一种可替代 profile 信息演示的工具叫做 xdebugtoolkit,一款基于 web 前端的叫做 Webgrind,和一款基于 java 的工具叫做 XCallGraph

如果你不能使用 KDE(或者不想使用 KDE)的 kcachegrind 包,可以用 perl 脚本 "ct_annotate",它能从分析器跟踪文件生成 ASCII 输出。

开启 profiler

profiling 开启是在 php.ini 中通过设置 xdebug.profiler_enable 设为 1 来完成。这指示 Xdebug 开始写入效能分析信息到 xdebug.profiler_output_dir 指令配置的转储目录中。生成的文件名总是以 "cachegrind.out" 开头,以 PHP(或者 Apache)进程的 PID(进程 ID)或者包含初始调试脚本的目录的 crc32 哈希码结尾。需要确保在 xdebug.profiler_output_dir 中有足够的空间,因为一个复杂脚本 profiler 生成的信息数量是巨大的,比如一个像 eZ Publish 的复杂应用能高达 500M。

你也可以通过将设置 xdebug.profiler_enable_trigger 设为 1 选择性的使用 profiler。如果它被设为 1,那么可以通过 XDEBUG_PROFILE 名字的 GET/POST 或者 COOKIE 变量来使用 profiler。Firefox 2 扩展也可以通过这个设置来使用调试器(查看 HTTP 调试会话)。为了让触发器能正常工作, xdebug.profiler_enable 需要被设置为 0.

从 Xdebug 2.6 开始,在被分析的请求上 Xdebug 添加了 HTTP 头部 X-Xdebug-Profile-Filename 。这个头部包含保存该请求分析信息的文件名。

分析 profiles

在一个效能信息文件生成之后可以使用 KCacheGrind 打开它:

一旦打开了文件,在 KCacheGrind 不同的面板上可以得到大量信息。在左侧可以找到 "Flat Profile" 面板,它显示了脚本中按花费的时间进行排序的所有函数,以及它所有的子单元。 第二栏 "Self" 显示了这个函数(不包括它的子单元)所花费的时间,第三栏 "Called" 显示了一个指定的函数被调用的频率,最后一栏 "Function" 显示了函数名。Xdebug 通过给函数名添加 "php::" 前缀来改变 PHP 内部函数名,也以一种指定的方式来处理包含的文件。调用 include(include_once,require 和 require_once)会让 "::" 和包含的文件名跟随其后。在左侧的截图中你可以看到 "include::/home/httpd/ez_34/v..."和 PHP 内部函数的例子 "php::mysql_query"。 前两列的数字可以是对于脚本运行时间总量的百分比(如示例中)或者是绝对的时间(一个单元是 1/1000000 秒)。你可以通过右边所看到的按钮切换这两种模式。

右边的面板包含一个上部和下部窗格。上边显示了哪个函数调用了当前指定的函数的信息 ("eztemplatedesignresource->executecompiledtemplate in the screenshot)。 下边显示了当前指定函数被调用的信息。

在上部的面板中 "Cost" 栏显示了在当前指定的函数中当从函数列表中被调用时所花费的时间。Cost 栏的数字合计总是 100%。下部面板中 "Cost" 栏显示了当从列表中调用这个函数所花费的时间。当统计这里列表里的数字,高概率的不能达到 100% ,因为指定的函数本身也需要花费时间来执行。

"All Callers" 和 "All Calls" 标签不仅显示了被单独调用的这个函数的直接调用,也显示了函数调用上上下下产生的更多层级。在截图的上部面板中左侧展示了所有函数调用当前指定的一个函数,包含其他函数和这个指定函数之间直接地和间接地的堆栈信息。"Distance" 栏展示了列出的函数和当前指定的这个之间有多少函数调用。如果两个函数之间有不同的距离,它将会显示为一个范围(例如 "5-24")。括号中的数字是距离的中位数。下部的面板中也是一样除了它显示的信息是从当前指定的函数调用的函数,也是直接或间接地方式。


相关设置


xdebug.profiler_aggregate
类型:整数,默认值: 0
当这个设置设为 1,将为多个请求编写单个分析文件。可以浏览多个页面或者重新加载页面以获得所有请求的平均值。这个文件将会命名为 .cachegrind.aggregate。 你需要移动这个文件以获得另一轮聚合数据。

xdebug.profiler_append
类型:整数,默认值: 0
如果这个设置设为 1,当一个新的请求映射到相同的文件(取决于 xdebug.profiler_enable_output_name 的设置)时 profiler 文件将不会被覆盖。反而新的 profile 将会被追加到文件中。

xdebug.profiler_enable
类型:整数,默认值: 0
开启 Xdebug 的 profiler 将会在 profile_output_directory 中创建文件。这些文件可以被 KCacheGrind 读取为可视化的数据。这个设置不能在脚本的 ini_set() 中设置。如果你想选择性的开启 profiler,请设置 xdebug.profiler_enable_trigger 为 1,而不是使用这个设置。

xdebug.profiler_enable_trigger
类型:整数,默认值:0
当这个设置设置为 1,通过使用 XDEBUG_PROFILE GET/POST 参数或者设置一个名 XDEBUG_PROFILE 的 cookie 将会触发生成 profiler 文件。这将会把 profiler 数据写入定义的目录。为了阻止 profiler 为每一个请求都生成 profile 文件,你需要设置 xdebug.profiler_enable 为 0。可以通过配置 xdebug.profiler_enable_trigger_value 来访问触发器本身。

xdebug.profiler_enable_trigger_value
类型:字符串,默认值: "", 由 Xdebug > 2.3 引入
这个设置可以用来限制在 xdebug.profiler_enable_trigger 中谁能利用 XDEBUG_PROFILE 功能进行概括。当将它的默认值更改为空字符串时,cookie 的值、GET 或者 POST 参数需要匹配设置在这个设置中的秘钥才能开启 profiler。

xdebug.profiler_output_dir
类型:字符串,默认值: /tmp
profiler 输出所在的这个目录将会被写入,需要确保运行 PHP 的用户有权限对这个目录进行写入。这个设置不能在脚本的 ini_set() 中设置。

xdebug.profiler_output_name
类型:字符串,默认值: cachegrind.out.%p

这个设置决定了用来转储跟踪信息的文件名。这个设置指定了格式化说明符的格式,非常类似于 sprintf() 和 strftime()。这里有几个格式化说明符可以用来格式化文件名。

查看 xdebug.trace_output_name 文档支持的说明符。


相关函数


string xdebug_get_profiler_filename()
返回 profile 信息的文件名

返回用来保存 profile 信息的文件的名字。