D3bd7339e1941bc25c05110b69a82721

This function generates a multi-column table from an array. Any improvements?

/**
 * Generates a multi-column table from an array 
 *
 * @param array		Array to process 
 * @param columns	Number of columns to return  
 * @param id		(Optional) ID attribute to attach to the table
 * @param class		(Optional) CSS class attribute to attach to the table 
 */
function generate_table($array, $columns, $table_id='', $table_class='') {
	$array_size = count($array);
	$col_size = ceil($array_size / $columns);
 
	$table = "<table";
	$table .= !empty($table_id) ? " id='".$table_id."'" : '';
	$table .= !empty($table_class) ? " class='".$table_class."'" : '';
	$table .= ">\n";
	for ($i = 0; $i < $col_size; $i++) {
		$table .= "\t<tr>";
		for ($j = 0; $j < $columns; $j++) {
			$table .= (($i+$j*$col_size) < $array_size) ? '<td>'.$array[$i+$j*$col_size].'</td>' : '<td>&nbsp;</td>';
		}
		$table .= "</tr>\n";
	}
	$table .= "</table>\n";
 
	return $table;
}

Refactorings

No refactoring yet !

5a00a3a98dcf6f9cd717440fd2b606e5

Eineki

July 24, 2009, July 24, 2009 12:36, permalink

1 rating. Login to rate!

Just for exercise, I've rewritten the two loops. The function become.
I don't know if it is more efficient, you should try (I can't do it now).

<?
/**
 * Generates a multi-column table from an array 
 *
 * @param array		Array to process 
 * @param columns	Number of columns to return  
 * @param id		(Optional) ID attribute to attach to the table
 * @param class		(Optional) CSS class attribute to attach to the table 
 */
function generate_table($array, $columns, $table_id='', $table_class='') {
	$table = "<table";
	$table .= !empty($table_id) ? " id='$table_id'" : '';
	$table .= !empty($table_class) ? " class='$table_class'" : '';
	$table .= ">\n";
	
	while (count($array)) {
                $row=array_pad(array_splice($array,0,$columns),$columns,'&nbsp');
		$table .='<tr><td>'.join($row,'</td><td>')."</td></tr>\n";
        }
	$table .= "</table>\n";	
	return $table;
}
?>
D3bd7339e1941bc25c05110b69a82721

gwrtheyrn

July 24, 2009, July 24, 2009 19:20, permalink

No rating. Login to rate!

eineki, your code looks great, and it works perfectly except that the ordering of the array output is horizontal, while the one in my solution returns vertically ordered columns. (i hope you understand, it's difficult to explain in english :)) but that doesn't really matter to me, so thanks.

F1e3ab214a976a39cfd713bc93deb10f

Tj Holowaychuk

July 27, 2009, July 27, 2009 05:32, permalink

No rating. Login to rate!

You shouldnt use count() in while, very inefficient. You should use a for loop and cache the length

64a0e7762e3bcc116f56161cb46354d5

Jelle

January 16, 2011, January 16, 2011 15:14, permalink

No rating. Login to rate!

Not really an improvement on this code, but I'm writing a database class (extending PDO) that returns a statement object (extending PDOStatement). In the statement class I wrote a fetchTable() method that returns a html table based on the resultset. Since this is the first result in google when you search for "generate table from array" I thought I'd share that code here.

<?php
class db extends PDO {
    //too much code to show here.
}


class dbStatement extends PDOStatement {

    /**
     * Fetches the next row from a result set as an associative array.
     * @return array
     * An associative array with the row data.
     */
    public function fetchAssoc() {
        return $this->fetch(PDO::FETCH_ASSOC);
    }

    public function fetchTable($attributes = array()){
        $table = "<table";
        $table .= !empty($table_id) ? " id='$table_id'" : '';
        $table .= !empty($table_class) ? " class='$table_class'" : '';
        foreach($attributes as $attribute => $value){
            if(is_array($value)){
                //support multiple classes (e.g. class = "class1 class2").
                $value = implode(" ", $value);
            }
            $table .= " " . $attribute . "=\"" . $value . "\"";
        }
        $table .= ">\n";
        $tableheaders = "";
        $rows = "";
        $header = "";
        while($row = $this->fetchAssoc()){
            if(empty($tableheaders)){
                $header .= "\t<tr>\n";
            }
            $rows .= "\t<tr>\n";
            foreach ($row as $fieldname => $field){
                if(empty($tableheaders)){
                    $header .= "\t\t<th>" . ucfirst(strtolower($fieldname)) . "</th>\n";
                }
                $rows .= "\t\t<td>" . $field . "</td>\n";
            }
            $rows .= "\t</tr>\n";
            if(empty ($tableheaders)){
                $header .= "\t</tr>\n";
                $tableheaders .= $header;
            }
        }
        $table .= $tableheaders . $rows . "</table>\n";
        return $table;
    }

}

/**
 * Usage example
 */

require_once '/includes/config.php';
require_once '/scripts/database/class.db.php';
    
$db = new db("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
$stmt = $db->select('menu')->run(); //returns a dbStatement object.
print $stmt->fetchTable();

/**
 * Prints following HTML
 * <table> 
 *      <tr> 
 *          <th>Id</th> 
 *          <th>Label</th> 
 *          <th>Page_id</th> 
 *          <th>Weight</th> 
 *      </tr> 
 *      <tr> 
 *          <td>1</td> 
 *          <td>First Page</td> 
 *          <td>1</td> 
 *          <td>1</td> 
 *      </tr> 
 *      <tr> 
 *          <td>2</td> 
 *          <td>Second Page</td> 
 *          <td>2</td> 
 *          <td>100</td> 
 *      </tr> 
 * </table> 
*/

?>
9976f490a102198d5d482d67099e076f

Mike Hoy

May 18, 2011, May 18, 2011 20:26, permalink

No rating. Login to rate!

einiki, Thank you very much for your code. I was dreading making a TON of tables cells and this script made my life so much easier. I nearly cried at how quickly all my perfect tables were generated. All I had was two td's per row so I just passed in empty values to the function.
echo generate_table($arr, 2, '', '');

Your refactoring





Format Copy from initial code

or Cancel