How to output (to a log) a multi-level array in a format that is human-readable?
Asked Answered
B

8

119

I'm working on a drupal site and when debugging, I am always having to read through long, nested arrays. As a result, a large portion of my life is spent using the arrow, return, and tab keys, to split up 1000+ character strings into a nested, readable format.

For drupal devs, I can't use devel's dsm(), as I'm working with multi-step #ahah/#ajax forms, and I can only output the arrays to the error log, not to the screen.

Visual example:

Evil:

array ( 'form_wrapper' => array ( '#tree' => true, '#type' => 'fieldset', '#prefix' => '', '#suffix' => '', '#value' => '', 'name' => array ( '#type' => 'textfield', '#title' => NULL, '#size' => 60, '#maxlength' => 60, '#required' => false, '#description' => NULL, '#attributes' => array ( 'placeholder' => 'Email', ), '#post' => array ( 'form_wrapper' => array ( 'name' => '', 'pass' => '', ),
...

Good:

array ( 
'form_wrapper' => array ( 
    '#tree' => true, 
    '#type' => 'fieldset', 
    '#prefix' => '<div>', 
    '#suffix' => '</div>', 
    '#value' => '', 
    'name' => array ( 
        '#type' => 'textfield', 
        '#title' => NULL, 
        '#size' => 60, 
        '#maxlength' => 60, 
        '#required' => false, 
        '#description' => NULL, 
        '#attributes' => array ( 
            'placeholder' => 'Email', 
        ), 

Edit: Sorry, by "not output to screen", I meant via drupal's system messages where it's possible to output arrays in a clickable, nested format (using devel.module).

Bord answered 9/8, 2012 at 13:46 Comment(1)
<?php echo '<pre>'.print_r($array,1).'</pre>'; ?>Clemenciaclemency
M
266

If you need to log an error to Apache error log you can try this:

error_log( print_r($multidimensionalarray, true) );

If you would like to capture the output of print_r(), use the return parameter. When this parameter is set to true, print_r() will return the information rather than print it.

Mesmerize answered 11/9, 2013 at 12:48 Comment(7)
Looks like it's print_r (lowercase). Does print_R really work as well?Nam
thanks @AkhilrajNS can you tell me more about how can i send the inserted query or any query which is executed above this log message.?Sang
@ankitsuthar Did you mean SQL Query ?Mesmerize
Yes But I got it by the last query function in CI. Actually, I want to log a data which are get inserted or edited, deleted.Sang
This is dum. This outputs newline characters as literal \n instead of actual newlines.Malonylurea
@Malonylurea I think may have missed the point in the first sentence. This targets the APACHE ERROR LOG which is a single entry per line. If you want to capture multi-line info it needs to be escaped.Shibboleth
@Shibboleth perhaps I missed Akhillaraj's point, but the OP asked for something human readable. Apparently this is an apache "security" fix: https://mcmap.net/q/188752/-why-does-my-apache2-log-output-replace-newlines-with-n. But the idea of print_r is to output the array in a human-readable way and apache kills that. His is the top answer, mysteriously. Well, maybe things changed since 2013. Or maybe he uses php-fpm or CGI.Malonylurea
S
23

http://php.net/manual/en/function.print-r.php This function can be used to format output,

$output = print_r($array,1);

$output is a string variable, it can be logged like every other string. In pure php you can use trigger_error

Ex. trigger_error($output);

http://php.net/manual/en/function.trigger-error.php

if you need to format it also in html, you can use <pre> tag

Schmooze answered 9/8, 2012 at 13:54 Comment(4)
Read the question - OP needs to do this for log output - not screen output.Incest
@Incest read the answer, if you need to format it also in htmlPhenolic
@Fivell, I try. If you clarify your answer to explain that the output can be sent to the log file, I'll remove my -1.Incest
@Schmooze there's a small issue with trigger_error it limits messages to max 1024 length or something similar. Making some longer var_exports/print_r strings get cut-off. It's useful for simple structures.Pap
C
15

I just wonder why nobody uses or recommends the way I prefer to debug an array:

error_log(json_encode($array));

Next to my browser I tail my server log in the console eg.

tail -f /var/log/apache2/error.log

Though it's debatable if the output is human-readable, but it's still my preferred way to read it and would look something like that:

[Tue Dec 13] [...] AH01071: Got error 'PHP message: {"form_wrapper":{"#tree":true,
"#type":"fieldset","#prefix":"","#suffix":"","#value":"","name":{"#type":
"textfield","#title":null,"#size":60,"#maxlength":60,"#required":false,
"#description":null,"#attributes":{"placeholder":"Email"},"#post":{
`"form_wrapper":{"name":"","pass":""}}}}}', referer: http://localhost/
Cumulus answered 13/9, 2019 at 20:52 Comment(1)
Because it's not "human readable" :D Seriously, this is a good idea though. A post-processor combined with jq can make this an excellent debugging toolMalonylurea
P
11

Simple stuff:

Using print_r, var_dump or var_export should do it pretty nicely if you look at the result in view-source mode not in HTML mode or as @Joel Larson said if you wrap everything in a <pre> tag.

print_r is best for readability but it doesn't print null/false values.

var_dump is best for checking types of values and lengths and null/false values.

var_export is simmilar to var_dump but it can be used to get the dumped string.

The format returned by any of these is indented correctly in the source code and var_export can be used for logging since it can be used to return the dumped string.

Advanced stuff:

Use the xdebug plug-in for PHP this prints var_dumps as HTML formatted strings not as raw dump format and also allows you to supply a custom function you want to use for formatting.

Pap answered 9/8, 2012 at 13:53 Comment(1)
Read the answer var_export allows you to return a string.Pap
V
2

Drupal's Devel module has other useful functions including ones that can print formatted arrays and objects to log files. See the guide at http://ratatosk.net/drupal/tutorials/debugging-drupal.html

dd()

Logs any variable to a file named “drupal_debug.txt” in the site’s temp directory. All output from this function is appended to the log file, making it easy to see how the contents of a variable change as you modify your code.

If you’re using Mac OS X you can use the Logging Console to monitor the contents of the log file.

If you’re using a flavor of Linux you can use the command “tail -f drupal_debug.txt” to watch the data being logged to the file.

Vellicate answered 9/8, 2012 at 13:55 Comment(0)
P
1

This will help you

echo '<pre>';

$output = print_r($array,1);

echo '</pre>';

EDIT

using echo '<pre>'; is useless, but var_export($var); will do the thing which you are expecting.

Phenolic answered 9/8, 2012 at 13:56 Comment(1)
@Incest When this parameter is set to TRUE, print_r() will return the information rather than print it.Phenolic
N
1

Syntax

print_r(variable, return);

variable Required. Specifies the variable to return information about

return Optional. When set to true, this function will return the information (not print it). Default is false

Example

error_log( print_r(<array Variable>, TRUE) );
Nernst answered 13/11, 2020 at 9:38 Comment(0)
T
0

You should be able to use a var_dump() within a pre tag. Otherwise you could look into using a library like dump_r.php: https://github.com/leeoniya/dump_r.php

My solution is incorrect. OP was looking for a solution formatted with spaces to store in a log file.

A solution might be to use output buffering with var_dump, then str_replace() all the tabs with spaces to format it in the log file.

Trifocals answered 9/8, 2012 at 13:51 Comment(2)
Read the question - OP needs to do this for log output - not screen output.Incest
I did read the question. Missed that last little comment. Thanks for letting me know. This solution is not going to work then.Trifocals

© 2022 - 2024 — McMap. All rights reserved.