Query Backtrace with Zend_Db_Profiler_Firebug + FirePHP + Xdebug
Posted by admin in Uncategorized on September 5th, 2009
Why? I needed to see a full backtrace of every query.
How? In order for this to work, you’ll need to patch Zend_Db_Profiler_Firebug.
== How I created the patch file ==
I created the patch using the instructions on http://framework.zend.com/wiki/display/ZFDEV/Submitting+a+Bug+Fix you need to create a side-by-side copy of the library/ directory from the untouched source and name it library.original.
$ cd /usr/local/zend/1.9.2 $ cp -R ../ZendFramework-1.9.2-minimal/library library.original $ ls -al drwxr-xr-x 3 laptop staff 102 Sep 5 08:22 library drwxr-xr-x 3 laptop staff 102 Sep 5 08:26 library.original
Now we can run the diff command from the instruction page.
$ diff --exclude='*.original' --exclude='*~' --exclude='*.rej' --ignore-space-change -ruN library.original/ library/ > ZF-ver-1.9.2-Zend_Db_Profiler_Firebug-changes-tbellefy.patch
Download the patch file here: ZF-ver-1.9.2-Zend_Db_Profiler_Firebug-changes-tbellefy.patch
== Using the patch ==
To patch the file on your server, download the patch file to the root directory of your Zend Framework. You should have something like this:
$ cd /usr/local/zend/1.9.2 $ wget http://timbellefy.com/wp-content/uploads/2009/09/ZF-ver-1.9.2-Zend_Db_Profiler_Firebug-changes-tbellefy.patch
Always do a –dry-run first. –verbose helps.
$ patch --dry-run --verbose --backup --strip=0 --unified --input=ZF-ver-1.9.2-Zend_Db_Profiler_Firebug-changes-tbellefy.patch
If everything looks ok, remove the –dry-run and apply the patch.
Usage: Using the Zend_Db_Profiler_Firebug is really simple. You just pass a profiler object to the Zend_Db::factory() and everything happens under the hood. The example I was using involves Zend_Queue so we need to create the queues database.
Example Setup:
$ mysql -uroot -ppassword mysql> create database `queues`; mysql> quit $ mysql -uroot -ppassword queues < library/Zend/Queue/Adapter/Db/queue.sql
Now create an index.php file that you can access with Firefox, something like http://localhost/index.php that contains the following code. By the way, this example uses the non-Front Controller style from here: http://framework.zend.com/manual/en/zend.db.profiler.html#zend.db.profiler.profilers.firebug.
<?php
set_include_path('/usr/local/zend/1.9.2/library');
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();
$channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
$channel->setRequest($request);
$channel->setResponse($response);
ob_start();
// Create a Firebug Profiler.
$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
// Pass the Firebug Profiler to the Zend_Db::factory().
$options = array(
'name' => 'myqueue',
'driverOptions' => array(
'host' => 'localhost',
'port' => '3306',
'username' => 'root',
'password' => 'password',
'dbname' => 'queues',
'type' => 'pdo_mysql',
Zend_Db::PROFILER => $profiler
)
);
// Create a database-based queue and add a message.
$queue = new Zend_Queue('Db', $options);
$queue->send('My Test Message');
// Flush profiling data to browser.
$channel->flush();
$response->sendHeaders();
echo "done.";
Make sure you have Firebug open and click on the Console tab. Open Firefox to http://localhost/index.php. You should see a line with something like: “All DB Queries (11 @ 0.00019 sec)”. Click to expand and you should see every query listed in order. The last column now contains a full backtrace leading up to each query! Click on one of the backtrace lines and it will pop open into a larger window for you.
Hope this helps you.
My setup:
Firefox 3.5.2
Firebug 1.4.2
FirePHP 0.3.1
Xdebug 2.0.5
PHP 5.3.0
Zend Framework 1.9.2
MySQL 5.1.32
Mac OSX 10.5.8
AJAX In Symfony 1.2
Prototype will automatically process an AJAX response as long as the correct content-type header is returned.
~/symfony/branches/1.2/lib/plugins/sfProtoculousPlugin/lib/helper/JavascriptHelper.php
/**
* Returns 'eval(request.responseText)', which is the Javascript function that
* 'form_remote_tag()' can call in 'complete' to evaluate a multiple update return document
* using 'update_element_function()' calls.
*/
function evaluate_remote_response()
{
return 'eval(request.responseText)';
}
This function automatically creates the “request.responseJSON;” object that we use below.
Top of ~/apps/$app/templates/layout.php
<div id="indicator" style="display:none;">Loading...</div> <h1>Basic letter</h1> Dear <span>name_here</span>, Your e-mail was received and will be answered shortly.
Bottom of ~/apps/$app/templates/layout.php
echo link_to_remote('Refresh the letter', array(
'url' => 'post/list',
//'complete' => 'updateJSON(request)',
'loading' => visual_effect('appear', 'indicator'),
'complete' => visual_effect('fade', 'indicator').
visual_effect('highlight', 'title').'updateJSON(request);'
));
echo javascript_tag("
function updateJSON(request)
{
json = request.responseJSON;
for (var i = 0; i < json.length; i++)
{
Element.update(json[i][0], json[i][1]);
}
}
");
In ~/apps/$appname/config/view.yml
all: javascripts: [%SF_PROTOTYPE_WEB_DIR%/js/prototype]
In ~/apps/$appname/modules/post/actions/actions.class.php
class postActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
}
public function executeList(sfWebRequest $request)
{
$this->setLayout(false);
sfConfig::set('sf_web_debug', false);
sfConfig::set('sf_debug', false);
if ($this->getRequest()->isXmlHttpRequest()) {
$this->getResponse()->setHttpHeader('Content-Type','application/json; charset=utf-8');
}
//$output = array(array("title" => "My basic letter", "name" => "Mr Brown"));
//return $this->renderText(json_encode($output));
$output = '[["title", "My basic letter"], ["name", "Mr Brown"]]';
return $this->renderText('('.$output.')');
}
}
Hello world!
Posted by admin in Uncategorized on February 18th, 2009
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
