I wanted to cleanly display tabular data from a PHP command line script, and I like how MySQL formats its output. This is quick, somewhat inefficient, hacky code, but it got the job done. You'll find nothing to be proud of in this code; I don't want to spend more time writing this post about it than I did writing it :)
/** * Out a MySQL-style table of data * * @param array $data Associative array of data to output. * @param array $header_keys Optional; Assoc array of display names to use for headers. Keys must match those of $data. Defaults to keys of $data. * @param string $glue String to join lines with, defaults to newline. * @return string * */ function build_table($data, $header_keys=array(), $glue="\n") { $table = ''; $data_fmt = array(); $divider_row = array(); $header_fmt = array(); $keys = array_keys($data[0]); $col_lengths = array_flip($keys); // used to determine the max column width if( empty($header_keys) ) { $header_keys = array_combine($keys, $keys); } // set the base max length to the length of our header keys foreach( $keys as $key ) { $col_lengths[$key] = strlen($header_keys[$key]); } foreach( $data as $row ) { foreach( $keys as $key ) { $col_lengths[$key] = max($col_lengths[$key], strlen($row[$key])); } } foreach( $keys as $key ) { $data_fmt[] = '%-' . $col_lengths[$key] . 's'; $header_fmt[] = '%-' . $col_lengths[$key] . 's'; $divider_row[] = str_pad('', $col_lengths[$key]+2, '-'); // fill the spacing } $data_fmt = '| ' . implode(' | ', $data_fmt) . ' |'; $divider_row = '+' . implode('+', $divider_row) . '+'; $header_fmt = '| ' . implode(' | ', $header_fmt) . ' |'; // assemble the table $table .= $divider_row . $glue; $table .= vsprintf($header_fmt . $glue, $header_keys); $table .= $divider_row . $glue; foreach( $data as $row ) { $table .= vsprintf($data_fmt . $glue, $row); } $table .= $divider_row . $glue; return $table; }
The output will be similar to:
+--------------------+--------------------+---------------+ | First | Second col | Random Column | +--------------------+--------------------+---------------+ | 60386980488376 | 597655305189574649 | 51 | | 959432 | 459191 | 396802 | | 73874213 | 570702 | 771 | | 144579584678722975 | 892300317939345 | 59180 | | 293172 | 314 | 127725766727 | +--------------------+--------------------+---------------+
It only works with associative arrays, but that's easy enough to fix. You can proudly test it out using this glorious snippet:
$data = array(); function get_rand() { $max=rand(1,6); $str=''; for( $i = 0; $i < $max; $i++ ) { $str .= rand(10, 1000); } return $str; } for( $i = 0; $i < 5; $i++ ) { $row = array( 'one' => get_rand(), 'two' => get_rand(), 'three' => get_rand(), ); $data[] = $row; } $disp = array( 'one' => 'First', 'two' => 'Second col', 'three' => 'Random Column', ); echo build_table($data, $disp);


