
Start debugging and profiling web applications
- From the sandbox
- Tutorial
Introduction
There are many articles on Habré that describe interesting and complex aspects of web development, but there are many readers who, being at the beginning of their career as a web developer, would like to see material that would take the first step from "PHP in 24 hours" to development at a serious level, and I would like to share my experience in this matter.
Features of the web application make it divided into two parts: client and server. On the client side, JavaScript code is working (maybe VBScript can be found somewhere, but we probably won’t consider this case), on the server side there are a lot of things, in principle, but we will consider PHP, the most popular language for server side of web applications. It would also be interesting to talk about debugging and profiling Flash applications on the client side, but the topic covered is already extensive, so for now let’s leave it alone.
The analysis and validation of HTML code can also be attributed to the tasks of debugging client code. This, it seems, is a task not entirely from the field of programming, but also important.
Some parts of the considered problems have already been considered in other articles, and I have provided links to them.
Debugging and profiling client code
The “classic” way to debug JavaScript code is to use a function
alert
and its derivatives. I remember that at the beginning of my career I personally wrote a function print_r
for JavaScript, because I did not see the possibility of outputting debugging information on arrays and objects. It looked something like this:function print_r(variable)
{
if (variable instanceof Array || variable instanceof Object) {
var key;
for (key in variable)
alert(key + ' => ' + variable[key]);
}
else {
alert(variable);
}
}
Of course, no profiling of speech was conducted at all.
With this approach, even information about the console object is revolutionizing.
The specifics of the client side of the web application requires code debugging in all popular browsers. Of course, debugging in Internet Explorer and any
Mozilla firefox
Perhaps Firefox can be called the pioneer in debugging client code. For a long time it was indicated as the browser most suitable for development, and all thanks to the Firebug extension , which probably contains all the necessary features, except for HTML code validation.

Also, starting with version 4, a built-in Web console appeared, which implements part of the Firebug’s Console and Network tab functions, as well as some CSS debugging capabilities.

Starting with version 6, a simple JavaScript editor appeared, which also implements one of Firebug's functions, and allows you to write and execute code directly in the browser.

Starting with version 10, the Page Inspector has appeared, which allows you to study HTML code and CSS properties, that is, it implements the functions of the HTML tab.

For validation of HTML code, the Html Validator extension is usually responsible . Just its icon indicating the number of errors on the main page of the site habrahabr.ru can be seen in the lower right corner of the browser in the picture with the Page Inspector.
Also, taking this opportunity, I will indicate that there are many extensions for this browser that make life easier, about which there was already a corresponding article on Habré .
Google Chrome and Safari
These WebKit-based browsers have a built-in Web Inspector development tool that is very well developed and implements almost the same functions as Firebug. At the same time, we must pay tribute to him, he does not slow down the browser, which is usual for the "big brother".

In Chrome, it can be called by keystroke
Ctrl+Shift+I
or simply by F12
. In Safari, it is well hidden, and to use it you need to enable development features in your browser settings. Later, the developer’s tools will be available from the “Development” item of the main menu or by keyboard shortcut Ctrl+Alt+I
. To validate HTML code, you also need to install third-party extensions. For example, for Chrome, it could be Validity . So far, Safari has not managed to find anything suitable.
Opera
Opera also has a built-in developer tool called “Opera Dragonfly”, and can be called up at any time using a keyboard shortcut
Ctrl+Shift+I
. It is similar to what WebKit represents to us, and has similar features and advantages, although, in my opinion, it is less convenient. 
As comrade homm suggested , Opera has a simple means of submitting a validation page to validator.w3.org. In the context menu of the display area of the site there is an item “Are web standards complied”, which is exactly responsible for this.
With extensions for HTML validation in the Opera directory, the situation is tense. For this reason, the Validator extension has no alternatives.
Internet explorer
Starting with version 8, the developer tools appeared here. It provides approximately the same capabilities as in the case of other browsers, but, as in other aspects of its activities, Internet Explorer provides them with some features and indescribable grace. An important point is the ability to emulate older versions, as well as compatibility mode.

It is generally accepted that in versions 7-, over which the seas of tears of typesetters and JS-programmers spilled, there are no such tools. There is a third-party solution, Companion.JS, about which there was a related article . Of course, its capabilities are significantly inferior to the usual tools, but this tool at least allows you to debug the code more advanced than the "alert-oriented debugging".
Comrade atdsuggested that for these long-suffering versions there was a “native” toolbox called “Internet Explorer Developer Toolbar”, but it required a separate installation: www.microsoft.com/download/en/details.aspx?id=18359
Also, comrade k12th recalled that if you have Visual Studio, you can debug the code in it (components of the "Web Development Tools"). You can also find information about the free version of Visual Web Developer Express .
Debugging and profiling server code
Xdebug
As we agreed at the beginning, we consider the case when PHP is used on the server. Here they are the “classic” debugging method
echo
, print_r
and var_dump
, but there is also a debugging tool, as in the best houses - Xdebug . For me personally, in connection with the specifics of studying at the institute, it looked "just like in Delphi." The xdebug extension allows you to at least run the code step by step and view the values of variables, which takes programming in PHP to a new level. On the intricacies of working with xdebug was a corresponding article . XDebug is usually available in GNU / Linux repositories; on Windows, it is also not too difficult to install by copying the dll file.
When using this extension, an incoming connection (by default to port 9000) arrives from the server to the developer's computer, which it must process. To do this, you must configure your IDE accordingly.
By the way, using the IDE is also a prerequisite for moving forward. Some programmers believe that the difference between programming in notepad with code highlighting and in the IDE can be seen only on large projects, but I personally am of the opinion that the difference is visible even on the program "Hello world!" - One automatic substitution of names and arguments of standard functions is worth what.
XHProf
About extension
Yes, xdebug provides profiling capabilities, but I personally like the development of Facebook for these purposes, XHProf . I honestly did not conduct any tests, but it is believed that this extension is much better suited for production-servers and for profiling under real loads.
Installation
Unfortunately, this extension is not included in any repositories. It is part of PECL, but for some reason, installing it in the regular way often causes problems. For this reason, you have to install from source.
# Получаем исходники
wget http://pecl.php.net/get/xhprof-0.9.2.tgz
# Распаковываем исходники
tar -xvf xhprof-0.9.2.tgz
# Переходим в каталог, где содержится код расширения
cd xhprof-0.9.2/extension/
# Проводим компиляцию и тест
phpize
./configure
make
make test
# Проводим установку цивилизованно
checkinstall
The configuration file
xhprof.ini
provides us with the following capabilities:[xhprof]
extension=/usr/local/lib/php/extensions/no-debug-non-zts-20090626/xhprof.so
; Каталог для логов
xhprof.output_dir="/var/log/xhprof/"
Profiling
The directory that we receive by unpacking the archive contains, in addition to the extension sources, a web interface for studying profiling results, and a library for profiling the application.
We give an example of profiling. The following elements must be included in the application code:
// Начало скрипта, включаем профилирование
// как нагрузки на процессор, так и на память
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
/*
* Основной код приложения
*/
// Конец скрипта, завершаем профилирование,
// записываем результат в лог
$xhprofData = xhprof_disable();
include_once XHPROF_DIR.'/xhprof_lib/utils/xhprof_lib.php';
include_once XHPROF_DIR.'/xhprof_lib/utils/xhprof_runs.php';
$xhprofRuns = new XHProfRuns_Default();
$namespace = 'some-unique-name';
$runId = $xhprofRuns->save_run($xhprofData, $namespace);
echo "\n";
Here the constant
XHPROF_DIR
points to the directory where we unpacked the downloaded archive. To analyze the results you need the same web interface. It can be taken in the catalog
$XHPROF_DIR/xhprof_html/
- conventionally denote it as follows. For example, we placed it in a place accessible to the web server, and it is available at the address example.com/system/xhprof/
, then to analyze the result of work we need to contact it as follows: example.com/system/xhprof/?run=%runId%&source=%namespace%
We will get a similar result: Profiling can be included in the application code on an ongoing basis, or, for example, make it run randomly with a certain probability or by the presence of a certain condition. For example, like this:

$needProfiler = (mt_rand(0, 100) < 10 or isset($_COOKIE['xhprof']));
if ($needProfiler)
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
In this case, if you have complaints from customers or suspicions, you can turn to profiling results for a certain time period. Using the parameter,
namespace
you can determine which part of the application (which script, controller, action) were profiled.Profiling SQL Queries
As a rule, working with a database is the bottleneck in the application. For this reason, query profiling is recommended. For example, consider part of a class that is a wrapper around mysql extension functions. Yes, I know that this extension is not very popular and wish him death no less than the good old IE6. I do not urge him to use, just this class is right at my fingertips.
/**
* Запрос
* @param string $sql Запрос
* @param array $params Параметры
* @param string $query Скомпилированный запрос
* @return array Результат
*/
public function query($sql, array $params = array(), &$query = '')
{
$start = microtime(TRUE);
// Проведение запроса, включая "защиту" параметров
$stop = microtime(TRUE);
$time = $stop - $start;
$this->_addProfilerData($sql, $time);
// Возврат результата
}
private function _addProfilerData($query, $time)
{
if (is_array(self::$profilerData)) {
self::$profilerData[] = array(
'query' => $query,
'time' => $time
);
}
}
public function __destruct()
{
if (is_array(self::$profilerData)) {
$this->_writeProfilerData();
self::$profilerData = FALSE;
}
// Отключение от БД
}
private function _writeProfilerData()
{
$values = array();
foreach (self::$profilerData as $row) {
$query = mysql_real_escape_string($row['query'], $this->con);
$time = (float)$row['time'];
$hash = crc32($row['query']);
$values[] = "($hash, '$query', $time)";
}
if ($values) {
$strValues = implode(', ', $values);
$sql = "INSERT DELAYED INTO `profiler_queries` (`query_hash`, `query`, `work_time`) VALUES $strValues";
@mysql_query($sql, $this->con);
}
}
Here, query profiling data is stored in a table
profiler_queries
. This table can be of the MyISAM or Archive type, since they provide the ability to make pending inserts, which does not create an unnecessary delay in the response when profiling. Also, for a better search of queries in the table, it is better to create a column of the type INT
where the crc32 hash of the query will be written, on which you want to create an index.Conclusion
The article turned out to be quite large. Perhaps I went upstairs here and touched on topics that have already been touched upon, but if I had read something similar in due time - an article where all the information was gathered together and useful links were given, this would be invaluable to me. I hope that my article will help someone on the path to enlightenment.
References
- We use console to the full
- Firebug: Part 1 - console
- Firefox Extensions for Web Development for All Occasions
- JavaScript debugger for IE
- Debugging PHP applications with xdebug
- PHP Profiling
- Pinba - real-time php monitoring (prompted by trueneutral )
- Webgrind - Xdebug profiling web frontend (suggested by truezemez )
- Internet Explorer Developer Toolbar
- XDEBUG EXTENSION FOR PHP
- XHProf (GitHub)