firephp_使用FirePHP调试PHP代码

firephpphp

As the technical manager of a suite of software projects, one of my duties is doing code reviews. One of the things I see far more often than I’d like when doing reviews is debugging PHP code committed and pushed up the chain. Raise your hand if you’ve done this:程序员

做为一套软件项目的技术经理,个人职责之一是进行代码审查。 我作评论时常常看到的事情之一就是调试已提交PHP代码并推高连接。 完成如下操做后举手: web

<?php
$total = $someService->getComplexTotal();
var_dump($total);
$someOtherService->processTotal($total);

Ok, so you don’t have to raise your hand. But chances are, you smiled a bit. Either “Yeah, how did he know I do that?” or “Yeah, I used to do that. But I have other ways of debugging now.” What an awesome segue!chrome

好的,因此您没必要举手。 可是机会是,你笑了一下。 要么“是,他怎么知道我这样作?” 或“是的,我曾经那样作。 可是我如今有其余调试方法。” 好厉害的segue! 数组

We should use a debugging method that does not display information to a non-programmers through the web page. That is to say, we should never see variable dumps or SQL statements echo’d to the screen. This can’t happen. 浏览器

咱们应该使用一种调试方法,该方法不会经过网页向非程序员显示信息。 也就是说,咱们永远都不会看到变量转储或SQL语句回显到屏幕上。 这不可能发生。 缓存

The safest method of debugging requires configuring your IDE to use a tool like Xdebug or Zend Debugger to trace currently executing code. This isn’t always practical. In the absence of using a fully configured debug environment, I turn to FirePHP.安全

最安全的调试方法是将IDE配置为使用Xdebug或Zend Debugger之类的工具来跟踪当前执行的代码。 这并不老是可行的。 在没有使用彻底配置的调试环境的状况下,我将转向FirePHP。 服务器

使用FirePHP进行更安全PHP调试 (Use FirePHP for Safer PHP Debugging)

FirePHP is a PHP library used to generate console messages in the browser from your PHP code. Console messages are generally created by JavaScript, but FirePHP sends similar messages as HTTP headers with the response from the server. Various browser extensions act as proxies for the JavaScript console methods and convert these headers into console log messages.app

FirePHP是一个PHP库,用于从您PHP代码在浏览器中生成控制台消息。 控制台消息一般由JavaScript建立,可是FirePHP会经过服务器的响应将相似的消息做为HTTP标头发送。 各类浏览器扩展都充当JavaScript控制台方法的代理,并将这些标头转换为控制台日志消息。

Why is this “safer” that outputting debug data? Well, when using methods like JavaScript’s console.log(), you need to make a concerted effort to view the debug messages. Normal visitors would not have the development console open on their browser, and therefore will not see your debug messages. If you’re outputting var_dump()‘s instead, there is no way NOT to see the messages.

为何这种“更安全”的输出调试数据? 好吧,当使用JavaScript的console.log()类的方法时,您须要共同努力以查看调试消息。 普通访问者没法在其浏览器上打开开发控制台,所以将看不到调试消息。 若是输出的是var_dump() ,则没法不查看消息。

Do note, I call this “safer,” but you still must take care not to leave FirePHP calls enabled with critical system information available in production.

请注意,我称此为“安全”,但您仍必须注意不要在生产环境中使用重要的系统信息使FirePHP调用保持启用状态。

设置FirePHP (Setting Up FirePHP)

Visit the FirePHP Core Install page to choose to download the library directly or get the commands to install via PEAR. If you use other frameworks, such as Zend Framework, log writers already exist for FirePHP so an additional download is not necessary.

访问FirePHP Core Install页面,选择直接下载该库或获取经过PEAR安装的命令。 若是您使用其余框架(例如Zend Framework),则FirePHP已经存在日志编写器,所以无需额外下载。

If you’re using Firefox, install FireBug for an expanded set of tools to debug your web applications, and then install the FirePHP extension to extend FireBug and intercept the FirePHP messages.

若是您使用的是Firefox,请安装FireBug以获取一组扩展的工具来调试Web应用程序,而后安装FirePHP扩展名以扩展FireBug并拦截FirePHP消息。

If you are using Chrome, simply install one extension FirePHP4Chrome. (Full disclosure: I created this Chrome extension and actively develop it. I hadn’t had a lot of luck with other plugins in Chrome.)

若是您使用的是Chrome,则只需安装一个扩展FirePHP4Chrome便可 。 (完整披露:我建立了这个Chrome扩展程序并积极进行开发。我对Chrome中的其余插件没有多大运气。)

Finally, open the console in your browser of choice. In Firefox, click the Firebug icon to display the console. Verify FirePHP is enabled by clicking the FirePHP icon in the console view and noting whether the check mark is next to enabled. In Chrome, click the settings icon, choose tools, and click ‘Developer Tools’ to display the console. FirePHP4Chrome will be automatically enabled when the console is opened.

最后,在您选择的浏览器中打开控制台。 在Firefox中,单击Firebug图标以显示控制台。 经过在控制台视图中单击FirePHP图标并注意是否选中复选标记来验证FirePHP是否已启用。 在Chrome中,点击设置图标,选择工具,而后点击“开发者工具”以显示控制台。 打开控制台后,FirePHP4Chrome将自动启用。

使用FirePHP进行基本日志记录 (Basic Logging With FirePHP)

If you’ve ever worked with different error level logging, you’ve undoubtedly seen the debate on the differences between what types of errors should be “warn” versus “error.” Or, whether you should you use “info” versus “log.” While I have my own opinions, I won’t bore you with them. Suffice to say there may be reasons to differentiate a message you want to send to the console in a different way than a standard message.

若是您曾经使用过不一样的错误级别日志记录,那么您无疑会看到关于应“警告”哪些类型的错误与“错误”之间的区别的争论。 或者,是否应该使用“信息”仍是“日志”。 尽管我有本身的看法,但我不会让您感到厌烦。 能够说,可能有理由区分您要发送到控制台的消息的方式不一样于标准消息。

The four types of messages that the FirePHP protocol supports currently are: log, info, warn, and error. I aim to show you how you can use each one. It is up to you to choose the proper one for your environment and the context of your debugging/logging.

FirePHP协议当前支持的四种消息类型是:日志,信息,警告和错误。 个人目的是向您展现如何使用每个。 您能够根据本身的环境和调试/记录的上下文来选择合适的解决方案。

The following code demonstrates how to include the FirePHP library and execute each of the logging types.

如下代码演示了如何包括FirePHP库以及如何执行每种日志记录类型。

<?php
require 'FirePHPCore/fb.php';

FB::log('Log message');
FB::info('Info message');
FB::warn('Warn message');
FB::error('Error message');

The above code simply includes the core FirePHP library and calls the various logging methods. There are multiple ways to call the library methods; it supports pure global function procedural calls, static method calls, and fully instantiated object calls. I use the static methods because I generally want to use FirePHP in only one line to send debug information; I want to do it quickly!

上面的代码仅包含核心FirePHP库,并调用了各类日志记录方法。 调用库方法有多种方法。 它支持纯全局函数过程调用,静态方法调用和彻底实例化的对象调用。 我使用静态方法是由于我一般只想在一行中使用FirePHP发送调试信息。 我想快点作!

Below, you’ll see screenshots with the output on both Firefox and Chrome.

在下面,您将看到在Firefox和Chrome上均显示输出的屏幕截图。

alt
alt

Firefox’s display is a bit prettier. The Chrome version does not have an icon for “info” because console.log() in Chrome does not support the icon yet. You’ll also notice later that the table output in Chrome is very rudimentary. This is because Chrome does not support console.table() in the non-experimental feature-set yet. While I use Chrome for my own development, I’ll use Firefox in my screenshots in the rest of this article.

Firefox的显示更漂亮。 Chrome版本没有用于“信息”的图标,由于Chrome中的console.log()尚不支持该图标。 稍后您还会注意到,Chrome中的表格输出很是简单。 这是由于Chrome还没有在非实验功能集中支持console.table() 。 当我使用Chrome进行本身的开发时,本文其他部分的屏幕快照中将使用Firefox。

To make the logging information more useful, it is possible to add a label to the log messages. This is specified as the second parameter of the logging methods.

为了使日志记录信息更加有用,能够在日志消息中添加标签。 这被指定为日志记录方法的第二个参数。

<?php
require 'FirePHPCore/fb.php';

$turtles = $zooService->fetchAllTurtles();
FB::info($turtles, "All Turtles");

As you see in the following screenshot, the zoo service in my example fetched three turtles. It was clear that this particular log message was turtles, and say, not famous actors or something else. To save space, Firebug/FirePHP has collapsed the output. Hover over the line to see the entire output.

以下面的屏幕截图所示,在个人示例中,动物园服务获取了三只乌龟。 很明显,这个特定的日志消息是乌龟,而不是著名演员或其余东西。 为了节省空间,Firebug / FirePHP折叠了输出。 将鼠标悬停在该行上能够查看整个输出。

alt

使用FirePHP进行高级日志记录 (Advanced Logging With FirePHP)

FirePHP is great for generating one-time log messages as I’ve already demonstrated. However, there are more advanced features which make FirePHP really shine. Three that I’ll cover quickly are message grouping, tables, and traces.

如前所述,FirePHP很是适合生成一次性日志消息。 可是,还有一些更高级的功能使FirePHP真正发挥做用。 我将快速介绍的三个是消息分组,表和跟踪。

分组 (Grouping)

Let’s pretend we have a bit of logging that we need to do in a loop. It could potentially get out of hand and make the console scroll. We may want to put that it a group so that it can easily be collapsed and expanded. In this sample code, I’ll log four entries of information I want grouped together.

假设咱们须要循环进行一些日志记录。 它可能会失控并使控制台滚动。 咱们可能但愿将其分组,以即可以轻松折叠和扩展它。 在此示例代码中,我将记录四个要分组在一块儿的信息条目。

<?php
require 'FirePHPCore/fb.php';

$specialHashes = array();
for ($x = 0; $x < 5; $x++) {
    $specialHashes[$x] = sha1($x . 'somesalt');
    FB::info($specialHashes[$x], "Hash #" . $x);
}

And the output:

并输出:

alt

The log message is slightly longer than I might like. I want to group it intelligently and allow for it to be collapsed. I have modified the code to include grouping methods built into FirePHP.

日志消息比我想要的时间长。 我想对其进行智能分组并容许其折叠。 我修改了代码,以包含FirePHP中内置的分组方法。

<?php
require 'FirePHPCore/fb.php';

$specialHashes = array();
FB::group('Special Hashes');
for ($x = 0; $x < 5; $x++) {
    $specialHashes[$x] = sha1($x . 'somesalt');
    FB::info($specialHashes[$x], "Hash #" . $x);
}
FB::groupEnd();

And now, the new output:

如今,新的输出:

alt

As you can see, there is now an option to minimize the group labeled “Special Hashes.” FirePHP even allows for a group to be collapsed by default. Simply replace the group() call and add an options array as follows:

如您所见,如今有一个选项能够最小化标记为“特殊哈希”的组。 FirePHP甚至容许默认状况下折叠组。 只需替换group()调用并添加一个options数组,以下所示:

FB::group('Special Hashes', array('Collapsed'=>true));

桌子 (Tables)

FirePHP can send tabular data pretty easily. In fact, since Firefox’s console.table() method is so great, the data displays beautifully and is easy to understand. (Oh Chrome, please catch up!) To send table data in FirePHP, an array of columns is used. However, the first element of the array must be the column names. Using our special hashes example, let’s log them as a table:

FirePHP能够很是轻松地发送表格数据。 实际上,因为Firefox的console.table()方法很是出色,所以数据显示精美且易于理解。 (哦,Chrome,请遇上!)要在FirePHP中发送表数据,将使用一列列。 可是,数组的第一个元素必须是列名。 使用咱们特殊的哈希示例,让咱们将它们记录为表格:

<?php
require 'FirePHPCore/fb.php';

$specialHashes = array();
for ($x = 0; $x < 5; $x++) {
    $specialHashes[] = array($x, sha1($x . 'somesalt'));
}

$headers = array('Hash #', 'Hash Value');
$logTable = array($headers) + $specialHashes;
FB::table("Special Hashes", $logTable);

You may notice one thing that I did a bit differently is the creation of the $logTable variable. Since the first element of the array sent to the table() method needs to be column labels, I created a temporary variable to do this task for me. I don’t want to manipulate the $specialHashes array – that is my business data. The table() method takes a Label parameter followed by the array of columns.

您可能会注意到,我作了一些不一样的事情是$logTable变量的建立。 因为发送到table()方法的数组的第一个元素须要是列标签,所以我建立了一个临时变量来为我完成此任务。 我不想操纵$specialHashes数组-这是个人业务数据。 table()方法采用Label参数,后跟列数组。

alt

When the console loads the data from FirePHP, the table is collapsed. For the above screenshot, I clicked the label to display the data.

当控制台从FirePHP加载数据时,该表将折叠。 对于上面的屏幕截图,我单击了标签以显示数据。

痕迹 (Traces)

Traces can be invaluable when debugging PHP code. Whether you want to couple them with a log message showing a variable’s value at specific point in the code or you need more information from an exception, trace is where it’s at. Very simply, you can call a trace anywhere in your PHP code with FirePHP as shown here:

调试PHP代码时,跟踪可能很是宝贵。 不管是要将它们与在代码中特定点处显示变量值的日志消息耦合在一块儿,仍是须要从异常中获取更多信息,跟踪都是它的所在。 很简单,您可使用FirePHP在PHP代码中的任何位置调用跟踪,以下所示:

<?php
require 'FirePHPCore/fb.php';

FB::trace('Simple Trace');

And the output:

并输出:

alt

When the output was displayed, I simply clicked on the label of “Simple Trace” to display the entire trace. This example is very simple and shows how easily it can be inserted into any code.

显示输出时,我只需单击“简单跟踪”的标签便可显示整个跟踪。 这个例子很是简单,展现了如何轻松地将其插入任何代码。

Let’s make a bit more complex of an example (although, I doubt you’ll actually want to make code like this in your project):

让咱们更复杂的示例(尽管我怀疑您是否真的想在项目中编写这样的代码):

<?php
require 'FirePHPCore/fb.php';

function one() {
    echo "This is one.<br>";
    two();
}

function two() {
    echo "This is two!<br>";
    FB::trace('Trace from function two.');
}

one();

Here, function one() is being called. Function two() is invoked in the last line of the function. After two() finishes, it executes a trace call to FirePHP. The following screenshot shows Firefox’s output:

在这里,函数one()被调用。 在函数的最后一行调用函数two()two()完成后,它将执行对FirePHP的跟踪调用。 如下屏幕截图显示了Firefox的输出:

alt

…还有更多! (… And There’s More!)

There is much more you can do with FirePHP than just the above examples. To view more information about specifying other options, setting up exception traces, and even using assertions, check out the FirePHP Headquarters.

使用FirePHP能够作的不只仅是上述示例。 要查看有关指定其余选项,设置异常跟踪甚至使用断言的更多信息,请查看FirePHP总部

奖励示例 (A Bonus Example)

As with most introduction style articles, the information here has been relatively generic and the examples mild. Need a bit more in-depth example to persuade you to use FirePHP? Let’s go:

与大多数介绍风格的文章同样,此处的信息相对通用,示例很少。 须要更深刻的例子来讲服您使用FirePHP吗? 咱们走吧:

<?php
try {
    $key = "user.{$userId}";
    if (!SimpleCache::has($key)) {
        FB::info($key, 'Cache miss:');
        $userService = new UserService();
        $user = $userService->fetchById($userId);
        SimpleCache::set($key, $user);
    }
    $user = SimpleCache::get($key);
}
catch (Exception $e) {
    FB::error($e);
    Router::generate500();
}

This simple example code is built to retrieve a user object. This system uses some type of caching and throws exceptions when a user is not available. The first time this code runs, the user is not cached so FirePHP sends an info message. For user ID of 5, the following screenshot shows the output.

这个简单的示例代码旨在检索用户对象。 该系统使用某种类型的缓存,并在用户不可用时引起异常。 第一次运行此代码时,不会缓存用户,所以FirePHP发送一条信息消息。 对于5的用户ID,如下屏幕截图显示了输出。

alt

The second time the code is ran, the method info() is not called and no message is sent to the console. Now, let’s imagine that the cache has become unavailable. (I could have created the code so that it could run if the cache wasn’t present, but that would just take away all of the fun!) In the case where the cache is no longer available, the set() method will throw an exception. The screen will show a nice error 500 message, according to this code. But, I’d like to see the exception and stack trace right away. That’s where the error() method comes in. It can interpret the Exception object and log it nicely for me.

第二次运行该代码时,不会调用方法info()也不会向控制台发送任何消息。 如今,让咱们想象一下缓存已不可用。 (我原本能够建立代码,以便在不存在缓存的状况下能够运行该代码,但这会带走全部的乐趣!)在缓存再也不可用的状况下, set()方法将抛出一个例外。 根据此代码,屏幕上将显示一条很好的错误500消息。 可是,我想当即看到异常和堆栈跟踪。 这就是error()方法的用处。它能够解释Exception对象并为我很好地记录它。

alt

摘要 (Summary)

The safest way to debug your PHP code is to use a debugger environment set up within your IDE. However, for quicker debugging as well as application level logging, FirePHP can play an important role.

调试PHP代码的最安全方法是使用在IDE中设置的调试器环境。 可是,对于更快的调试以及应用程序级别的日志记录,FirePHP能够发挥重要做用。

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/debugging-php-code-with-firephp/

firephp