php调试xdebug_使用Xdebug调试和分析PHP

Xdebug是一款免费开源的PHP扩展,提供调试、性能分析等功能,支持堆栈跟踪、代码覆盖率等。本文介绍如何在Netbeans中配置Xdebug进行PHP应用调试,以及如何在KCachegrind中读取性能分析报告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

php调试xdebug

PHP is the most popular language for web development, but a common criticism against it used to be that it lacked a suitable debugger. Developers using languages like Java and C# enjoy a powerful suite of debugging tools, often integrated directly with their IDEs. But the disconnected nature of web servers and PHP IDEs prevented us from having many of the same tools available. We manually added debug statements in our code… until Xdebug filled the void.

PHP是Web开发中最流行的语言,但对它的普遍批评过去是它缺乏合适的调试器。 使用Java和C#等语言的开发人员可以使用功能强大的调试工具套件,这些工具通常直接与其IDE集成。 但是Web服务器和PHP IDE的脱节本质使我们无法使用许多相同的工具。 我们在代码中手动添加了调试语句……直到Xdebug填补了空白。

Xdebug is a free and open source project by Derick Rethans and is probably one of the most useful PHP extensions. It provides more than just basic debugging support, but also stack traces, profiling, code coverage, and so on. In this article you’ll see how to install and configure Xdebug, how to debug your PHP application from Netbeans, and how to read a profiling report in KCachegrind.

Xdebug是Derick Rethans的免费开源项目,并且可能是最有用PHP扩展之一。 它不仅提供基本的调试支持,而且还提供堆栈跟踪,性能分析,代码覆盖率等等。 在本文中,您将看到如何安装和配置Xdebug,如何从Netbeans调试PHP应用程序以及如何在KCachegrind中读取性能分析报告。

安装和配置Xdebug (Installing and Configure Xdebug)

If you are using XAMPP or MAMP, Xdebug comes preinstalled; you just need to enable it in your php.ini. If you are using a package based installation on a platform such as Ubuntu, you can install it through your package manager with a command like apt-get install php5-xdebug.

如果您使用的是XAMPP或MAMP,则预装Xdebug。 您只需要在php.ini启用它即可。 如果在Ubuntu等平台上使用基于软件包的安装,则可以使用apt-get install php5-xdebug这样的命令通过软件包管理器进行apt-get install php5-xdebug

The entries for Xdebug in my php.ini look like this:

我的php.ini Xdebug的条目如下所示:

[xdebug]
zend_extension="/Applications/MAMP/bin/php5.2/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so"
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=9000

zend_extension specifies the path to the Xdebug module. The xdebug.remote_enable value toggles whether the extension is active or not. xdebug.remote_host is the name or the IP address of your system (here I’ve specified localhost because I’m working all on the same machine, but the value can be an IP Address or a DNS hostname if you need to specify something different for your setup). xdebug.remote_port is the port on which the client listens for a connection from Xdebug (9000 is the default value).

zend_extension指定Xdebug模块的路径。 xdebug.remote_enable值切换扩展名是否处于活动状态。 xdebug.remote_host是系统的名称或IP地址(此处我指定localhost是因为我都在同一台计算机上工作,但是如果您需要指定其他名称,则该值可以是IP地址或DNS主机名为您的设置)。 xdebug.remote_port是客户端侦听来自Xdebug的连接的端口(默认值为9000)。

When you use Xdebug, it’s important to make sure you are not using any other Zend extensions since they may conflict with Xdebug.

使用Xdebug时,确保您没有使用任何其他Zend扩展很重要,因为它们可能与Xdebug冲突。

There are other installation options as well. The Xdebug website provides a simple wizard to guide you through installation. You can take the output of phpinfo() or php –i and paste it in the text box and have the wizard analyze your server’s configuration and instruct you on how to compile Xdebug for your machine.

还有其他安装选项。 Xdebug网站提供了一个简单的向导来指导您完成安装。 您可以将phpinfo()php –i的输出粘贴到文本框中,并让向导分析服务器的配置并指导您如何为计算机编译Xdebug。

调试 (Debugging)

More often than not it’s tempting to use the var_dump() and exit/die() combination for debugging. But the problem with this approach is that you have to modify the code for debugging; you must remember every place you added output statements and remove them after debugging is finished. Xdebug overcomes this by letting you pause your application’s execution where ever you want. Then you can inspect the variables’ values in that scope to get better insight into what PHP is doing.

通常,很容易使用var_dump()exit / die()组合进行调试。 但是这种方法的问题在于,您必须修改代码以进行调试。 您必须记住添加输出语句的每个位置,并在调试完成后将其删除。 Xdebug通过让您在任何需要的地方暂停应用程序的执行来克服了这一问题。 然后,您可以检查该范围内的变量值,以更好地了解PHP的功能。

You can easily configure Netbeans to act as an Xdebug client. Open the options window (Tools > Options) and go to the debugging tab for the PHP section. Enter the debugging port given in php.ini and a Session ID which you’ll need to pass with the requests you want to debug. Now you’ll be able to run the debugger by clicking Debug in the tools tab.

您可以轻松地将Netbeans配置为充当Xdebug客户端。 打开选项窗口(工具>选项),然后转到PHP部分的调试标签。 输入php.ini提供的调试端口和会话ID,您需要将其与要调试的请求一起传递。 现在,您可以通过单击“工具”选项卡中的“调试”来运行调试器。

alt

With your source file open, press the Debug button in the toolbar to start debugging. It will open up the application in a browser, and PHP’s execution will pause at the first line of the file if you have enabled the “Stop at first line” option in the Options window. Otherwise, it will run until it encounters the first breakpoint. From there you can continue to the next break point using the continue button.

在源文件打开的情况下,按工具栏中的“调试”按钮开始调试。 如果您在“选项”窗口中启用了“在第一行停止”选项,它将在浏览器中打开应用程序,并且PHP的执行将在文件的第一行暂停。 否则,它将一直运行直到遇到第一个断点。 从那里可以使用继续按钮继续到下一个断点。

Notice in the brower’s URL bar the XDEBUG_SESSION_START parameter. To trigger the debugger you must pass XDEBUG_SESSION_START as a request parameter (GET/POST) or XDEBUG_SESSION as a cookie parameter.

注意浏览器的URL栏中的XDEBUG_SESSION_START参数。 要触发调试器,您必须传递XDEBUG_SESSION_START作为请求参数(GET / POST)或XDEBUG_SESSION作为cookie参数。

There are some other useful actions in the debugging toolbar. They are:

调试工具栏中还有一些其他有用的操作。 他们是:

  • Step over – Step over the currently executing line

    单步执行-单步执行当前执行的行
  • Step into – Step into the function (for non-built-in functions)

    进入–进入功能(对于非内置功能)
  • Step out – Step out of the current function

    退出–退出当前功能

You can add breakpoints by clicking the line number in the editor’s margin and then pause execution on them. They can be removed by clicking on them again. Alternatively, go to Window > Debugging > Breakpoints which will list all breakpoints in your program and you can select/deselect only those you needed.

您可以通过在编辑器的空白处单击行号来添加断点,然后在其上暂停执行。 可以通过再次单击将其删除。 或者,转到“窗口”>“调试”>“断点”,它将列出程序中的所有断点,并且您可以仅选择/取消选择所需的断点。

While running, the state of the variables in the current scope are shown in the variables window. It will show the values of local variables and super global variables like $_COOKIE, $_GET, $_POST and $_SERVER. You can watch their values change as you step through through the statements.

运行时,当前作用域中变量的状态显示在变量窗口中。 它将显示局部变量和超全局变量(例如$_COOKIE$_GET$_POST$_SERVER 。 在逐步执行语句时,您可以观察它们的值更改。

alt

剖析 (Profiling)

Profiling is the first step when optimizing any application. Profiling tools record important details like the time it takes for statements and functions to execute, the number of times they are called, and so on. The output can be analyzed to understand where the bottlenecks are.

分析是优化任何应用程序的第一步。 概要分析工具记录重要的细节,例如执行语句和函数所花费的时间,调用它们的次数等等。 可以分析输出以了解瓶颈在哪里。

Xdebug can also be used as a profiling tool for PHP. To start profiling your applications, add the following settings to php.ini:

Xdebug也可以用作PHP的分析工具。 要开始对应用程序进行性能分析,请将以下设置添加到php.ini

xdebug.profiler_enable = 1
xdebug.profiler_output_name = xdebug.out.%t
xdebug.profiler_output_dir = /tmp
xdebug.profiler_enable_trigger = 1

Profiling is disabled by default in Xdebug, so xdebug.profiler_enable is used to enable it. xdebug.profiler_output_name is the filename of the profiler log (the %t specifier appends a timestamp to the filename; see the documentation for a full list of specifiers). Xdebug stores the profiling output in the directory specified by xdebug.profiler_output_dir. You can can change this to a location of your choice, but remember it must have write permissions for the user account under which the PHP script is run.

Xdebug中默认情况下禁用分析,因此使用xdebug.profiler_enable启用它。 xdebug.profiler_output_name是事件探查器日志的文件名(%t说明符在文件名后附加时间戳; 有关说明符的完整列表, 请参阅文档 )。 Xdebug将分析输出存储在xdebug.profiler_output_dir指定的目录中。 您可以将其更改为您选择的位置,但是请记住,它必须对运行PHP脚本的用户帐户具有写权限。

Profiling degrades performance since the PHP engine need to look af each function call and log its details, so you don’t want to run it all the time. xdebug.profiler_enable_trigger instructs Xdebug to perform profiling only when XDEBUG_PROFILE is passed as a GET or POST parameter.

由于PHP引擎需要查看每个函数调用并记录其详细信息,因此性能分析会降低性能,因此您不想一直运行它。 xdebug.profiler_enable_trigger指示Xdebug仅在将XDEBUG_PROFILE作为GET或POST参数传递时执行性能分析。

The log file created by Xdebug can be small or large depending on what the application is doing. Also, it’s not really reader friendly. You’ll want to use programs like KCachegrind or Webgrind to view them. KCachegrind is a profile data visualization tool for KDE, which needs a Unix environment to run, whereas Webgrind is a web-based tool.

Xdebug创建的日志文件可以很小也可以很大,这取决于应用程序在做什么。 此外,它并不是真正的读者友好型。 您将要使用KCachegrindWebgrind之类的程序来查看它们。 KCachegrind是用于KDE的配置文件数据可视化工具,需要运行Unix环境,而Webgrind是基于Web的工具。

Opening the profiling long file in KCachegrind will show the cost of each function call starting at main(). Here is the KCachegrind visualization of profiling output of a function to find a factorial:

在KCachegrind中打开分析长文件将显示从main()开始的每个函数调用的成本。 这是KCachegrind可视化,用于分析函数的输出以查找阶乘:

alt

The left side panel (Function Profile) shows the time taken by each function in their execution order. The top right panel graphically displays the same information with the size corresponding to the cost of the function. The call graph represents the relationship between functions in the application. In this example there are only two functions, main() and fact(). fact() is a recursive function, which is indicated using a cycle in the graph.

左侧面板(功能配置文件)显示了每个功能按其执行顺序所花费的时间。 右上方的面板以图形方式显示相同的信息,其大小对应于功能成本。 调用图表示应用程序中功能之间的关系。 在此示例中,只有两个函数main()fact()fact()是一个递归函数,使用图中的循环表示。

While optimizing your code, you should look for the areas with highest total cost. More often than not, I/O operations will have the highest cost. Remember to reduce them as much as possible. Lazy load files wherever that makes sense.

优化代码时,您应该寻找总成本最高的区域。 通常,I / O操作的成本最高。 记住要尽量减少它们。 在有意义的地方延迟加载文件。

Suppose you have a class named Orders which will give you a list of all orders and their details from your web store.

假设您有一个名为Orders的类,它将为您提供来自网络商店的所有订单及其详细信息的列表。

<?php
class Orders
{
    protected $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }
    
    public function getAll() {
        $orders = array();
        $query = "SELECT * FROM orders";
        $result = $this->db->query($query);
        while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
            $row['details'] = 
                $this->getDetails($row['orderId']);
            $orders[] = $row;
        }

        return $orders;
    }
    
    public function getDetails($orderId){
        $details = array();
        $result = $this->db->query("SELECT * FROM orderdetails WHERE orderId = " . $orderId);
        while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
            $details[] = $row;
        }
        return $details;
    }
}

This class has two methods: getAll() and getDetails(). When you call the getAll() method, it will get all of the records from the orders table and loop through them to get the details of all records.

此类有两个方法: getAll()getDetails() 。 当您调用getAll()方法时,它将从订单表中获取所有记录并遍历它们以获取所有记录的详细信息。

Let’s have a look at the profiling information.

让我们看一下分析信息。

alt

Though the absolute figures are not significant since they depend on the platform and runtime conditions, you will get an idea about relative cost of different functions. Notice that some functions are called hundreds of times (which is bad of course). The code doesn’t need to loop through all of the orders and get the details of each order individually. Let’s rewrite the getAll() function to use a JOIN instead.

尽管绝对数字并不重要,因为它们取决于平台和运行时条件,但是您将对不同功能的相对成本有所了解。 注意,有些函数被调用了数百次(当然是不好的)。 该代码不需要遍历所有订单并单独获取每个订单的详细信息。 让我们重写getAll()函数以使用JOIN代替。

<?php
pubilc function getAll() {
    $orders = array();
    $query = "SELECT * FROM orders o
        JOIN orderdetails d ON o.orderId = od.Id
        ORDER BY o.orderId
        ";
    $result = $this->db->query($query);
    while($row =$result->fetch(PDO::FETCH_ASSOC)){
        $orders[] = $row;
    }
    return $orders;
}

Now the profiling yields a better result since the number of queries has decreased. Also, the code isn’t calling the getDetails() function any more.

现在,由于查询数量减少了,因此分析产生了更好的结果。 另外,该代码不再调用getDetails()函数。

alt

摘要 (Summary)

Xdebug act as a middleman that controls the execution of PHP programs in the server. In this article you’ve seen two of the most impressive features of Xdebug – debugging support and profiling support.

Xdebug充当中间人,控制服务器中PHP程序的执行。 在本文中,您已经看到了Xdebug的两个最令人印象深刻的功能–调试支持和性能分析支持。

Its remote debugging allows you to inspect values at runtime, without modifying your program, to get a better understanding of what PHP is doing. Profiling helps uncover bottlenecks in your code so you can optimize it for better performance.

它的远程调试功能使您可以在运行时检查值,而无需修改程序,以更好地了解PHP的功能。 分析有助于发现代码中的瓶颈,因此您可以对其进行优化以获得更好的性能。

I hope this article helps you realize the benefits of Xdebug and encourages you to start using it right away if you aren’t already. And if you find this a valuable tool, you might even want to consider supporting this great project by buying a support agreement.

我希望本文可以帮助您认识Xdebug的好处,并鼓励您立即开始使用Xdebug。 而且,如果您发现这是一个有价值的工具,您甚至可能要考虑通过购买支持协议来支持这个出色的项目。

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/debugging-and-profiling-php-with-xdebug/

php调试xdebug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值