Have you ever wanted to display the contents of an array as a table in a command line script? If so, you will have no doubt realised that it takes somewhat longer than it’s html equivalent.
I needed to output some data in a tabular format from a PHP CLI script this week. MySQL does a good job of this with it’s own command line interface, so my first hope was that someone may have replicated this in a PHP function. After a fair bit of searching on Google, I still couldn’t find a suitable tool, so I decided to write my own.
Please note that it is not perfect; e.g. it will break with unpredictable results if the array you pass to it is not correctly formed. However, if you want a quick function that converts an array to a table, then this will certainly help:
<style type="text/css">
* {font-family:courier new;}
</style>
<?
/*
//////////////////////////////////////////////////////
// FUNCTION: draw_text_table ($table)
// Accepts an array ($table) and returns a text table
// Array must be of the form:
$table[1]['id'] = '1';
$table[1]['make'] = 'Citroen';
$table[1]['model'] = 'Saxo';
$table[1]['version'] = '1.4 West Coast';
$table[2]['id'] = '2';
$table[2]['make'] = 'Honda';
$table[2]['model'] = 'Civic';
$table[2]['version'] = '1.6 VTi';
$table[3]['id'] = '3';
$table[3]['make'] = 'BMW';
$table[3]['model'] = '3 Series';
$table[3]['version'] = '328 Ci';
//////////////////////////////////////////////////////
*/
function draw_text_table ($table) {
// Work out max lengths of each cell
foreach ($table AS $row) {
$cell_count = 0;
foreach ($row AS $key=>$cell) {
$cell_length = strlen($cell);
$cell_count++;
if (!isset($cell_lengths[$key]) || $cell_length > $cell_lengths[$key]) $cell_lengths[$key] = $cell_length;
}
}
// Build header bar
$bar = '+';
$header = '|';
$i=0;
foreach ($cell_lengths AS $fieldname => $length) {
$i++;
$bar .= str_pad('', $length+2, '-')."+";
$name = $i.") ".$fieldname;
if (strlen($name) > $length) {
// crop long headings
$name = substr($name, 0, $length-1);
}
$header .= ' '.str_pad($name, $length, ' ', STR_PAD_RIGHT) . " |";
}
$output = '';
$output .= $bar."\n";
$output .= $header."\n";
$output .= $bar."\n";
// Draw rows
foreach ($table AS $row) {
$output .= "|";
foreach ($row AS $key=>$cell) {
$output .= ' '.str_pad($cell, $cell_lengths[$key], ' ', STR_PAD_RIGHT) . " |";
}
$output .= "\n";
}
$output .= $bar."\n";
return $output;
}
$table[1]['id'] = '1';
$table[1]['make'] = 'Citroen';
$table[1]['model'] = 'Saxo';
$table[1]['version'] = '1.4 West Coast';
$table[2]['id'] = '2';
$table[2]['make'] = 'Honda';
$table[2]['model'] = 'Civic';
$table[2]['version'] = '1.6 VTi';
$table[3]['id'] = '3';
$table[3]['make'] = 'BMW';
$table[3]['model'] = '3 Series';
$table[3]['version'] = '328 Ci';
echo 'This function takes an array like this:<br /><pre>';
var_dump($table);
echo '</pre>And converts it into a text table like this:<br /><pre>';
echo draw_text_table ($table);
echo '</pre>Handy for command line output!';
?>
I was just going to write one of these from scratch up today, you saved me, what I though was going to be about an hour, or as you explained, probroly more!
Serisouly wicked. We must be the only ones that use php on the command line. 😀
– Allan Button
Hi Paul, thanks for posting your code. I had a similar need and hacked together a little class recently.
Hi there,
I modified a bit your function to take into account the length of the keys :
function drawTextTable($table)
{
# add header length to table
$headers = array_keys($table[0]);
foreach ($headers as $key => $header)
{
$headers[$header] = $header;
unset($headers[$key]);
}
$ttable = $table;
$ttable[] = $headers;
# Work out max lengths of each cell
foreach ($ttable AS $row)
{
$cell_count = 0;
foreach ($row AS $key => $cell)
{
$cell_length = strlen($cell);
$cell_count++;
if (!isset($cell_lengths[$key]) || $cell_length > $cell_lengths[$key])
{
$cell_lengths[$key] = $cell_length;
}
}
}
# Build header bar
$bar = ‘+’;
$header = ‘|’;
$i = 0;
foreach ($cell_lengths AS $fieldname => $length)
{
$i++;
$bar .= str_pad(”, $length + 2, ‘-‘).’+’;
$name = $fieldname;
if (strlen($name) > $length)
{
# crop long headings
$name = substr($name, 0, $length-1);
}
$header .= ‘ ‘.str_pad($name, $length, ‘ ‘, STR_PAD_BOTH) . ‘ |’;
}
$output = ”;
$output .= $bar.”\n”;
$output .= $header.”\n”;
$output .= $bar.”\n”;
# Draw rows
foreach ($table AS $row)
{
$output .= “|”;
foreach ($row AS $key=>$cell)
{
$output .= ‘ ‘.str_pad($cell, $cell_lengths[$key], ‘ ‘, STR_PAD_RIGHT).’ |’;
}
$output .= “\n”;
}
$output .= $bar.”\n”;
return $output;
}
Regards
Zend now provide a class to do this:
http://framework.zend.com/manual/en/zend.text.table.introduction.html
takes care of fieldnames that are longer than actual values:
function draw_text_table ($table) {
// Work out max lengths of each cell
foreach ($table AS $row) {
$cell_count = 0;
foreach ($row AS $key=>$cell) {
$cell_length = strlen($cell);
$cell_count++;
//if($cell_length $cell_lengths[$key]) $cell_lengths[$key] = $cell_length;
}
}
// Build header bar
$bar = ‘+’;
$header = ‘|’;
$i=0;
foreach ($cell_lengths AS $fieldname => &$length) {
$i++;
$name = $i.”) “.$fieldname;
if (strlen($name) > $length) {
// crop long headings
// $name = substr($name, 0, $length-1);
$length=strlen($name);
}
$bar .= str_pad(”, $length+2, ‘-‘).”+”;
$header .= ‘ ‘.str_pad($name, $length, ‘ ‘, STR_PAD_RIGHT) . ” |”;
}
$output = ”;
$output .= $bar.”n”;
$output .= $header.”n”;
$output .= $bar.”n”;
// Draw rows
foreach ($table AS $row) {
$output .= “|”;
foreach ($row AS $key=>$cell) {
$output .= ‘ ‘.str_pad($cell, $cell_lengths[$key], ‘ ‘, STR_PAD_RIGHT) . ” |”;
}
$output .= “n”;
}
$output .= $bar.”n”;
return $output;
}
There is one more recipe: http://jkeks.com/archives/53
There are convert tabbed (\t) text table to beautify view
I’m lazy to code, and lazy to write. Therefore:
// Work out max lengths of each cell
foreach ($table AS $row) {
foreach ($row AS $key=>$cell) $cell_lengths[$key] = max(@$cell_lengths[$key], strlen($cell));
}
done