How do you display the contents of an object that has private and protected properties - which means dpm($object) doesn't give you what you want?
You could do this:
dpm('<pre>' . print_r($object, TRUE) . '</pre>');
But that's a lot to type and you get a huge horrible list (particularly if it's a View object).
Try this instead:
dpm((array) $object);
Works a treat.
And while we're on the subject of dpm() have you tried this:
dpm($var, __FUNCTION__);
or
dpm($var, __METHOD__);
It can help.
Showing posts with label debug. Show all posts
Showing posts with label debug. Show all posts
Wednesday, 5 March 2014
Monday, 23 September 2013
Field Complete and Profile2
So I thought I'd promote the latest dev version of my Field Complete module to a release candidate yesterday. There were two reasons for this: (a) it's pretty solid, and (b) people are more likely to use it if it's out of dev.
It wasn't a mistake. Within a couple of hours I had a new bug report: Doesn't work with Profile2.
Which surprised me a lot, why on earth would it not work with a popular entity-based module? My code is very standard and does nothing naughty.
The answer, of course, is that Profile2 is naughty. Or at least it's non-standard. I'm not going to go into detail but they bypassed standard edit-form processing and do odd awkward things with the display URL. So my form interceptions don't get a chance to work and the completeness progress bar (and the Incomplete fields block) can't work.
What to do?
On the one hand I don't see why I should hack my code to work with something non-standard. On the other, Profile2 is a very popular module and using Field Completeness with it is a natural thing to do. And I want people to use my module.
So I spent a couple of hours figuring out the nasty that Profile2 does and modifying my code to cope with it. It wasn't too horrible, but I can't say I enjoyed it as a process. My nice clean code now has hacks in it.
Oh well.
It wasn't a mistake. Within a couple of hours I had a new bug report: Doesn't work with Profile2.
Which surprised me a lot, why on earth would it not work with a popular entity-based module? My code is very standard and does nothing naughty.
The answer, of course, is that Profile2 is naughty. Or at least it's non-standard. I'm not going to go into detail but they bypassed standard edit-form processing and do odd awkward things with the display URL. So my form interceptions don't get a chance to work and the completeness progress bar (and the Incomplete fields block) can't work.
What to do?
On the one hand I don't see why I should hack my code to work with something non-standard. On the other, Profile2 is a very popular module and using Field Completeness with it is a natural thing to do. And I want people to use my module.
So I spent a couple of hours figuring out the nasty that Profile2 does and modifying my code to cope with it. It wasn't too horrible, but I can't say I enjoyed it as a process. My nice clean code now has hacks in it.
Oh well.
Monday, 30 January 2012
Little debugging aid
I had been having a real problem tracking down a PHP error in Drupal which was passing an array to htmlspecialchars() in check_plain() instead of a string. I needed to use debug_backtrace() but the issue was related to Views which meant that the arguments being passed at higher levels were catastrophically huge.
It was a real problem, using krumo just resulted in out-of-memory errors. And the problem was also happening inside AJAX calls so any attempt to simply print the output was doomed.
I needed a way to get a function backtrace which was not too verbose, didn't crash the machine and would work in an AJAX call.
The solution is the following routine which takes a debug_backtrace() extracts only the information we need and outputs to a file. It's not Drupal-specific but you may need to set up the directory:
/**
* Backtrace to a file for when nothing else works
*/
function debug_backtrace_file($fname = 'backtrace') {
$file = fopen("c:\\tmp\\{$fname}.log", 'ab');
if (!$file) {
return;
}
fputs($file, '=============== ' . date('Y-m-d H:i:s') . " ===============\n");
$line = __LINE__;
foreach (debug_backtrace() as $entry) {
$function = $entry['function'];
if ($function!=__FUNCTION__) {
if (isset($entry['class']) && $entry['class']) {
$function = "{$entry['class']}::$function";
}
fputs($file, sprintf("function %s at line %d in file %s\n", $function, $line, isset($entry['file'])?$entry['file']:t('unknown')));
}
$line = $entry['line'];
}
fclose($file);
}
Happy bug hunting.
It was a real problem, using krumo just resulted in out-of-memory errors. And the problem was also happening inside AJAX calls so any attempt to simply print the output was doomed.
I needed a way to get a function backtrace which was not too verbose, didn't crash the machine and would work in an AJAX call.
The solution is the following routine which takes a debug_backtrace() extracts only the information we need and outputs to a file. It's not Drupal-specific but you may need to set up the directory:
/**
* Backtrace to a file for when nothing else works
*/
function debug_backtrace_file($fname = 'backtrace') {
$file = fopen("c:\\tmp\\{$fname}.log", 'ab');
if (!$file) {
return;
}
fputs($file, '=============== ' . date('Y-m-d H:i:s') . " ===============\n");
$line = __LINE__;
foreach (debug_backtrace() as $entry) {
$function = $entry['function'];
if ($function!=__FUNCTION__) {
if (isset($entry['class']) && $entry['class']) {
$function = "{$entry['class']}::$function";
}
fputs($file, sprintf("function %s at line %d in file %s\n", $function, $line, isset($entry['file'])?$entry['file']:t('unknown')));
}
$line = $entry['line'];
}
fclose($file);
}
Happy bug hunting.
Labels:
backtrace,
check_plain,
debug,
debug_backtrace,
PHP,
views
Tuesday, 19 April 2011
Conditions for using where
Just to help you avoid spending as many hours as I have trying to force a nasty little query with a subquery to do what I wanted...
If you want to have a WHERE clause that contains something like "fss.entity_id = n.nid", you can't use the condition function. In other words, you can't do this:
$query->condition('fss.entity_id', 'n.nid');
You have to use this:
$query->where('fss.entity_id = n.nid');
Because the first version gets translated into fss.entity_id = 'n.nid' in the SQL, which will never be true.
In debugging this it slowly became obvious that something fundamental was wrong - because when I output the $query string and then replaced the placeholders with the right arguments, and shoved it straight into the MySQL server - it worked.
Eventually it dawned on me to use the Devel query output to see what was actually being called and found the error - though by that time I was looking for it, having exhausted every other option.
Here's a quick tip for outputting the entire contents of an object which contains public and private properties:
dpm(print_r($object, TRUE));
I could have done without that today.
If you want to have a WHERE clause that contains something like "fss.entity_id = n.nid", you can't use the condition function. In other words, you can't do this:
$query->condition('fss.entity_id', 'n.nid');
You have to use this:
$query->where('fss.entity_id = n.nid');
Because the first version gets translated into fss.entity_id = 'n.nid' in the SQL, which will never be true.
In debugging this it slowly became obvious that something fundamental was wrong - because when I output the $query string and then replaced the placeholders with the right arguments, and shoved it straight into the MySQL server - it worked.
Eventually it dawned on me to use the Devel query output to see what was actually being called and found the error - though by that time I was looking for it, having exhausted every other option.
Here's a quick tip for outputting the entire contents of an object which contains public and private properties:
dpm(print_r($object, TRUE));
I could have done without that today.
Subscribe to:
Posts (Atom)