Location: PHPKode > projects > PHP HTMLTables > php-htmltables/index.php
<?php
/**
* table.class.php - quick and dirty table classes
*
* @author	Aaron D. Campbell <hide@address.com>
*
* @todo make rowspan work with 0 as parameter (0 is to span ALL rows)
* @todo find a way to better clean up Table::prep_table(), specifically all the nested loops and conditions (especially the foreachs)
*
* @version 1.1
*
* Changes:
* 1.1:
*   Cell::__construct was modified, and all initialization requiring parameters were moved to Cell::initialize(), and all parameters passed to the construct are passed directly through to initialize.  This allows Row::add_cell to act as a Factory method, and use user_call_func_array to call initialize (whereas it cannot call new Cell).
*   Row::__construct was modified, and all initialization requiring parameters were moved to Row::initialize(), and all parameters passed to the construct are passed directly through to initialize.  This allows Table::add_* to act as a Factory methods, and use user_call_func_array to call initialize (whereas it cannot call new Rell).
*   Table::add_head_row, Table::add_body_row, and Table::add_foot_row were all modified to pass any number of parameters to Row::initialize().  This allows future changes to Row::initialize or Row::__construct() without changing these functions.
*   Table::add_row() was modified to act as an alias for add_body_row
*   Row::add_cell was modified like all the other add functions, for the same reasons.
*   Added support for colspan=0.  Colspan=0 means to span the entire row, therefore if there are other cells in the row, colspan=0 is removed, and cells are added to the end of the row as usual to compensate.
*   Empty cells are now fixed via Cell::get_cell().  This allows you to create an instance of Row, and have Cells assigned to it, without having an instance of Table.  The reason is that if you exceed thousands of rows, your momor limit for PHP might be exceeded.  This way, you can create a row, and then dump it (allowing you to still apply style attributes to all cells using a foreach, etc).
*   Updated to use array_diff($arrayName,array('')); to remove empty array elements (I had my own function, but this is more efficient)
*
* 1.0: original version
*/


/*
* Cell - basic cell creation
*/
class Cell{

	//$settings - array - containing all possible settings as keys
	public $settings = array('data'=>NULL, 'abbr'=>NULL, 'rowspan'=>NULL,
													 'colspan'=>NULL, 'id'=>NULL, 'style'=>NULL, 'class'=>NULL,
													 'lang'=>NULL, 'dir'=>NULL, 'title'=>NULL, 'onclick'=>NULL,
													 'ondblclick'=>NULL, 'onmousedown'=>NULL,
													 'onmouseup'=>NULL, 'onmouseover'=>NULL,
													 'onmousemove'=>NULL, 'onmouseout'=>NULL,
													 'onkeypress'=>NULL, 'onkeydown'=>NULL, 'onkeyup'=>NULL,
													 'align'=>NULL, 'char'=>NULL, 'charoff'=>NULL,
													 'valign'=>NULL);
	//$data is this cell's data, and $th is a bool telling if the cell is a header cell
	public $data, $th;

	/**
	*	public function __construct
	*
	*	All params get passed directly to Cell::initialize().	Please see the
	*	Cell::initialize() notes for more information
	* 
	*	@return void
	*/
	public function __construct(){
		$args = func_get_args();
		call_user_func_array(array($this, 'initialize'),$args);
	}
	/**
	*	public function initialize
	*	
	*	@param string $data			The data for the cell
	*	@param array	$settings	an associative array containing any of the following keys:
	*		'abbr' - string - abbreviation for header cell
	*		'rowspan' - int - number of rows spanned by cell
	*		'colspan' - int - number of columns spanned by cell
	*		'id' - string - document-wide unique id for cell
	*		'style' - string - style info for cell
	*		'class' - string - space-separated list of classes for cell
	*		'lang' - string - language code for contents of cell
	*		'dir' - string - direction for weak/neutral text in cell (LTR | RTL)
	*		'title' - string - advisory title
	*		'align' - string - align, text alignment (left | center | right | justify | char)
	*		'char' - string - alignment char, e.g. char=':'
	*		'charoff' - string - offset for alignment char
	*		'valign' - string - vertical alignment in cell (top | middle | bottom | baseline)
	*		The following Intrinsic events all correspond to their names, and are strings:
	*				'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover',
	*				'onmousemove', 'onmouseout', 'onkeypress', 'onkeydown', 'onkeyup'
	*
	*	@param bool	 $th	tells whether the cell is a header cell (<th>).
	*										Defaults to FALSE
	*
	*	Please note thataccording to w3 standards
	*	(http://www.w3.org/TR/html4/index/attributes.html), align and valign are NOT
	*	depreciated as of 04/04/2005 for the following: COL, COLGROUP, TBODY, TD, TFOOT,
	*	TH, THEAD, or TR
	*
	*	@return void
	*/
	public function initialize($data=NULL, $settings=array(), $th=false){
		//remove all empty settings.	They are useless.
		$settings = array_diff($settings,array(''));

		//Check that dir, align, and valign are set to acceptable values per w3 standards
		if(isset($settings['dir'])){
			$options = array('rtl', 'ltr');
			$settings['dir'] = strtolower($settings['dir']);
			if(!in_array($settings['dir'],$options)){unset($settings['dir']);}
		}

		if(isset($settings['align'])){
			$options = array('left', 'center', 'right', 'justify', 'char');
			$settings['align'] = strtolower($settings['align']);
			if(!in_array($settings['align'],$options)){unset($settings['align']);}
		}

		if(isset($settings['valign'])){
			$options = array('top', 'middle', 'bottom', 'baseline');
			$settings['valign'] = strtolower($settings['valign']);
			if(!in_array($settings['valign'],$options)){unset($settings['valign']);}
		}

		/*
		* go through each setting.	If the setting is valid (a key exists in
		* $this->settings for it) set the value accordingly
		*/
		foreach ($settings as $setting => $value) {
			if (array_key_exists(strtolower($setting),$this->settings)) {
				$this->settings[$setting] = $value;
			}
		}

		$this->data = $data;
		$this->th = $th;
	}
	
	/**
	* public function get_cell
	* 
	* Assembles the cell, including all it's settings, and returns the proper HTML as
	* a string.  It also fixes empty cells by adding an &nbsp;
	* 
	* @return string
	*/
	public function get_cell(){
		//set the cell type to 'th' or 'td' depending on $this->th
		$cell_type = ($this->th) ? 'th' : 'td';

		//$c is the html for the cell
		$c = "			<{$cell_type}";

		//step through the settings for the cell, and add any that are set
		foreach($this->settings as $setting => $value){
			if(isset($value)){$c .= " {$setting}=\"{$value}\"";}
		}
		if ($this->data == '') {$this->data = '&nbsp;';}
		$c .= ">{$this->data}</{$cell_type}>\r\n";
		return $c;
	}
}

/*
* Row - basic row creation
*/
class Row{
	//$cells is an array containing references to each instance of a Cell in this Row
	public $cells = array();
	//$settings - array - containing all possible settings as keys
	public $settings = array('id'=>NULL, 'style'=>NULL, 'class'=>NULL, 'lang'=>NULL,
													 'dir'=>NULL, 'title'=>NULL, 'onclick'=>NULL,
													 'ondblclick'=>NULL, 'onmousedown'=>NULL,
													 'onmouseup'=>NULL, 'onmouseover'=>NULL,
													 'onmousemove'=>NULL, 'onmouseout'=>NULL,
													 'onkeypress'=>NULL, 'onkeydown'=>NULL, 'onkeyup'=>NULL,
													 'align'=>NULL, 'char'=>NULL, 'charoff'=>NULL,
													 'valign'=>NULL);
	//$cur_cell = reference pointing to the last added instance of Cell
	public $cur_cell;
	public $restart_colors;

	/**
	*	public function __construct
	*
	*	All params get passed directly to Cell::initialize().	Please see the
	*	Cell::initialize() notes for more information
	* 
	*	@return void
	*/
	public function __construct(){
		$args = func_get_args();
		call_user_func_array(array($this, 'initialize'),$args);
	}

	/**
	*	public function initialize
	*
	*	@param array	$settings	 an associative array containing any of the following keys:
	*		'id' - string - document-wide unique id for row
	*		'style' - string - style info for row
	*		'class' - string - space-separated list of classes for row
	*		'lang' - string - language code for contents of row
	*		'dir' - string - direction for weak/neutral text in row (LTR | RTL)
	*		'title' - string - advisory title
	*		'align' - string - align, text alignment (left | center | right | justify | char)
	*		'char' - string - alignment char, e.g. char=':'
	*		'charoff' - string - offset for alignment char
	*		'valign' - string - vertical alignment in row (top | middle | bottom | baseline)
	*		The following Intrinsic events all correspond to their names, and are strings:
	*				'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover',
	*				'onmousemove', 'onmouseout', 'onkeypress', 'onkeydown', 'onkeyup'
	*
	*	Please note thataccording to w3 standards
	*	(http://www.w3.org/TR/html4/index/attributes.html), align and valign are NOT
	*	depreciated as of 04/04/2005 for the following: COL, COLGROUP, TBODY, TD, TFOOT,
	*	TH, THEAD, or TR
	*
	*	@return void
	*/
	public function initialize($settings=array(),$restart_colors=false){
		//remove all empty settings.	They are useless.
		$settings = array_diff($settings,array(''));

		//Check that dir, align, and valign are set to acceptable values per w3 standards
		if(isset($settings['dir'])){
			$options = array('rtl', 'ltr');
			$settings['dir'] = strtolower($settings['dir']);
			if(!in_array($settings['dir'],$options)){unset($settings['dir']);}
		}

		if(isset($settings['align'])){
			$options = array('left', 'center', 'right', 'justify', 'char');
			$settings['align'] = strtolower($settings['align']);
			if(!in_array($settings['align'],$options)){unset($settings['align']);}
		}

		if(isset($settings['valign'])){
			$options = array('top', 'middle', 'bottom', 'baseline');
			$settings['valign'] = strtolower($settings['valign']);
			if(!in_array($settings['valign'],$options)){unset($settings['valign']);}
		}

		/*
		* go through each setting.	If the setting is valid (a key exists in
		* $this->settings for it) set the value accordingly
		*/
		foreach ($settings as $setting => $value) {
			if (array_key_exists(strtolower($setting),$this->settings)) {
				$this->settings[$setting] = $value;
			}
		}
		$this->restart_colors = $restart_colors;
	}

	/**
	*	public function add_cell
	*
	*	All params get passed directly to Cell::initialize.	Please see the
	*	Cell::initialize notes for more information
	* 
	*	Creates a new instance of the Cell class, and adds it to the end of the cells
	*	array
	* 
	*	updates $this->cur_cell to point to the new cell
	*
	*	@return void
	*/
	public function add_cell(){
		$args = func_get_args();
		$this->cells[] = new Cell();
		$this->cur_cell =& $this->cells[sizeof($this->cells)-1];
		call_user_func_array(array($this->cur_cell,'initialize'),$args);
	}

	/**
	*	public function get_row
	*
	*	Assembles the row, including all it's settings and cells, and returns the proper
	*	HTML as a string
	*
	*	@return string
	*/
	public function get_row(){
		//$r is the html for the row
		$r = '		<tr';

		//step through the settings for the Row, and add any that are set
		foreach($this->settings as $setting => $value){
			if(isset($value)){$r .= " {$setting}=\"{$value}\"";}
		}
		$r .= ">\r\n";

		//step through all the cells, and add them to the row
		foreach($this->cells as $cell){$r .= $cell->get_cell();}
		$r .= "		</tr>\r\n";
		return $r;
	}
}

/*
*	Table - basic table creation
*/
class Table{
	/*
	*	$head_rows is an array containing references to each instance of a Row that
	*	are part of the head (thead) of the table
	*/
	public $head_rows = array();

	/*
	*	$body_rows is an array containing references to each instance of a Row that
	*	are part of the body (tbody) of the table
	*/
	public $body_rows = array();

	/*
	*	$foot_rows is an array containing references to each instance of a Row that
	*	are part of the head (tfoot) of the table
	*/
	public $foot_rows = array();

	//$settings - array - containing all possible settings as keys
	public $settings = array('id'=>NULL, 'style'=>NULL, 'class'=>NULL, 'lang'=>NULL,
													 'dir'=>NULL, 'title'=>NULL, 'onclick'=>NULL,
													 'ondblclick'=>NULL, 'onmousedown'=>NULL,
													 'onmouseup'=>NULL, 'onmouseover'=>NULL,
													 'onmousemove'=>NULL, 'onmouseout'=>NULL,
													 'onkeypress'=>NULL, 'onkeydown'=>NULL, 'onkeyup'=>NULL,
													 'frame'=>NULL, 'rules'=>NULL, 'summary'=>NULL,
													 'width'=>NULL, 'border'=>0, 'cellspacing'=>0,
													 'cellpadding'=>0);

	public $row_colors = NULL;
	//$cur_row = reference pointing to the last added instance of Row
	public $cur_row;

	/*
	*	Number of rows and columns in the table.
	*	$num_rows in incremented
	*	$num_cols is set inside prep_table()
	*/
	public $num_cols = 0;
	public $num_rows = 0;

 /**
	*	public function __construct
	*
	*	@param array	$settings	 an associative array containing any of the following keys:
	*		'id' - string - document-wide unique id for row
	*		'style' - string - style info for row
	*		'class' - string - space-separated list of classes for row
	*		'lang' - string - language code for contents of row
	*		'dir' - string - direction for weak/neutral text in row (LTR | RTL)
	*		'title' - string - advisory title
	*		'frame' - string - which parts of table frame to render
	*							(void|above|below|hsides|lhs|rhs|vsides|box|border)
	*		'rules' - string - rulings between rows and cols (none|groups|rows|cols|all)
	*		'summary' - string - purpose/structure for speech output
	*		'width' - string - table width
	*		'border' - int - controls frame width around table
	*		'cellspacing' - int - spacing between cells
	*		'cellpadding' - int - spacing within cells
	*		'row_colors' - array | string - array OR comma-seperated values, these are
	*							background colors, given in hex, that alternate for each row.
	*							They will NOT override a color set for a specific row.
	*							They default to: #FFFFFF & #EFEFEF
	*		The following Intrinsic events all correspond to their names, and are strings:
	*							'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover',
	*							'onmousemove', 'onmouseout', 'onkeypress', 'onkeydown', 'onkeyup'
	*
	*	@return void
	*/
	public function __construct($settings = array()){
		//remove all empty settings.	They are useless.
		$settings = array_diff($settings,array(''));

		//Check that dir, frame, and rules are set to acceptable values per w3 standards
		if(isset($settings['dir'])){
			$options = array('rtl', 'ltr');
			$settings['dir'] = strtolower($settings['dir']);
			if(!in_array($settings['dir'],$options)){unset($settings['dir']);}
		}

		if(isset($settings['frame'])){
			$options = array('void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'vsides', 'box', 'border');
			$settings['frame'] = strtolower($settings['frame']);
			if(!in_array($settings['frame'],$options)){unset($settings['frame']);}
		}

		if(isset($settings['rules'])){
			$options = array('none', 'groups', 'rows', 'cols', 'all');
			$settings['rules'] = strtolower($settings['rules']);
			if(!in_array($settings['rules'],$options)){unset($settings['rules']);}
		}

		//get the row_colors to alternate
		if(isset($settings['row_colors'])){
			if(!is_array($settings['row_colors'])){
				if(strtolower($settings['row_colors']) == 'none'){
					$this->row_colors = NULL;
				} else {
					$this->row_colors = explode(',',$settings['row_colors']);
				}
			}else{$this->row_colors = $settings['row_colors'];}
			if(isset($this->row_colors)){
				foreach($this->row_colors as $key => $value){
					if(!preg_match('/^#/',$value)){$this->row_colors[$key] = '#'.$this->row_colors[$key];}
				}
			}
			unset($settings['row_colors']);
		}else{$this->row_colors = array('#FFFFFF','#EFEFEF');}

		/*
		*	go through each setting.	If the setting is valid (a key exists in
		*	$this->settings for it) set the value accordingly
		*/
		foreach($this->settings as $setting => $value){
			if(array_key_exists(strtolower($setting),$settings)){
				$this->settings[$setting] = $settings[$setting];
			}
		}
	}

	/**
	*	public function add_row
	*
	*	All params get passed directly to Row::initialize.	Please see the
	*	Row::initialize notes for more information
	* 
	*	Creates a new instance of the Row class, and adds it to the end of the body_rows
	*	array (rows that will go into tbody)
	*
	*	updates $this->cur_row to point to the new Row
	*
	*	@return Row
	*/
	public function &add_row(){
		$args = func_get_args();
		return call_user_func_array(array($this,'add_body_row'),$args);
	}

	/**
	*	public function add_body_row
	*
	*	All params get passed directly to Row::initialize.	Please see the
	*	Row::initialize notes for more information
	* 
	*	Creates a new instance of the Row class, and adds it to the end of the body_rows
	*	array (rows that will go into tbody)
	*
	*	updates $this->cur_row to point to the new Row
	*
	*	@return Row
	*/
	public function &add_body_row(){
		$args = func_get_args();
		$this->body_rows[] = new Row();
		$this->cur_row = $this->body_rows[sizeof($this->body_rows)-1];
		call_user_func_array(array($this->cur_row,'initialize'),$args);
		return $this->cur_row;
	}

	/**
	*	public function add_head_row
	*
	*	All params get passed directly to Row::initialize.	Please see the
	*	Row::initialize notes for more information
	* 
	*	Creates a new instance of the Row class, and adds it to the end of the body_rows
	*	array (rows that will go into tbody)
	*
	*	updates $this->cur_row to point to the new Row
	*
	*	@return Row
	*/
	public function &add_head_row(){
		$args = func_get_args();
		$this->head_rows[] = new Row();
		$this->cur_row = $this->head_rows[sizeof($this->head_rows)-1];
		call_user_func_array(array($this->cur_row,'initialize'),$args);
		return $this->cur_row;
	}

	/**
	*	public function add_foot_row
	*
	*	All params get passed directly to Row::initialize.	Please see the
	*	Row::initialize notes for more information
	* 
	*	Creates a new instance of the Row class, and adds it to the end of the body_rows
	*	array (rows that will go into tbody)
	*
	*	updates $this->cur_row to point to the new Row
	*
	*	@return Row
	*/
	public function &add_foot_row(){
		$args = func_get_args();
		$this->foot_rows[] = new Row();
		$this->cur_row = $this->foot_rows[sizeof($this->foot_rows)-1];
		call_user_func_array(array($this->cur_row,'initialize'),$args);
		return $this->cur_row;
	}

	/**
	*	public function get_table
	* 
	*	Assembles the table, including all it's settings and rows, and returns the proper
	*	HTML as a string
	* 
	*	@return string
	*/
	public function get_table(){
		//run prep_table to fix minor errors, etc.
		$this->prep_table();

		//run change_colspan0 to fix colspan=0 problem with IE (IE does not support it)
		$this->change_colspan0();

		//$t is the html for the row
		$t = '<table';

		//step through the settings for the table, and add any that are set
		foreach($this->settings as $setting => $value){
			if(isset($value)){$t .= " {$setting}=\"{$value}\"";}
		}
		$t .= ">\r\n";

		//Add all the rows, in the correct order (head, foot, body)
		//step through all the head_rows, and add them to the table in thead tags
		if(sizeof($this->head_rows) > 0){
			$t .= "	<thead>\r\n";
			foreach($this->head_rows as $row){$t .= $row->get_row();}
			$t .= "	</thead>\r\n";
		}

		//step through all the foot_rows, and add them to the table in tfoot tags
		if(sizeof($this->foot_rows) > 0){
			$t .= "	<tfoot>\r\n";
			foreach($this->foot_rows as $row){$t .= $row->get_row();}
			$t .= "	</tfoot>\r\n";
		}

		//step through all the body_rows, and add them to the table in tbody tags
		if(sizeof($this->body_rows) > 0){
			$t .= "	<tbody>\r\n";
			foreach($this->body_rows as $row){$t .= $row->get_row();}
			$t .= "	</tbody>\r\n";
		}
		$t .= "</table>\r\n";
		return $t;
	}

	/**
	*	private function change_colspan0
	*
	*	Checks all cells, and if colspan is set to '0' it changes it to the total 
	*	columns in the table.	This is because IE does not support the w3 standard where
	*	colspan="0" means "span the whole table"
	*
	*	@return void
	*/
	private function change_colspan0(){
		$row_groups = array('head_rows'=>$this->head_rows,'body_rows'=>$this->body_rows,'foot_rows'=>$this->foot_rows);
		foreach($row_groups as $rows){
			foreach($rows as $row){
				foreach($row->cells as $cell){
					if((isset($cell->settings['colspan'])) && ($cell->settings['colspan'] == '0')){
						$cell->settings['colspan'] = $this->num_cols;
					}
				}
			}
		}
	}

	/**
	*	private function find_diff
	*
	*	@param array $c	an array of cells per row in a table
	*
	*	Modifies an array to how many cells need to be added to each row, in order for
	*	the table to be right
	*
	*	@return void
	*/
	private function find_diff(&$c){
		if($c != NULL){$c = $this->num_cols - $c;}else{$c = 0;}
	}

	/**
	*	private function prep_table
	*
	*	Fixes common errors with HTML tables:
	*		All rows are adjusted to be the same length
	*
	*	Also adds alternating row colors
	*
	*	@return void
	*/
	private function prep_table() {
		$color = 0;
		$cols_from_rowspan = array();
		$col_count = array();

		//put all row arrays into an array, so we can loop through them in order that
		//they appear.	This helps with rowspans
		$row_groups = array('head_rows'=>$this->head_rows,'body_rows'=>$this->body_rows,'foot_rows'=>$this->foot_rows);

		//step through row groups (head, body, foot)
		foreach($row_groups as $key=>$rows){
			//add element to the $col_count array, correspoding to the current group
			$col_count[$key] = array();
			//step through the rows in the current row_group
			foreach($rows as $row){
				//$cells is used to calculate the number of cells in each row
				$cells = 0;
				//add in cells from previous row spans
				if(isset($cols_from_rowspan[0])){$cells += array_shift($cols_from_rowspan);}

				//step through each cell in the current row
				foreach($row->cells as $cell){
					//if there IS a colspan set, compensate
					if(isset($cell->settings['colspan'])){
						//if colspan is NOT set to 0, increment cell count by colspan
						if($cell->settings['colspan'] != '0'){
							$cells += $cell->settings['colspan'];
						}
						//if colspan IS set to 0, and There are more cells in this row...unset
						//colspan...you can't have colspan=0 & have more cells
						elseif(count($row->cells) != 1){
							unset($cell->settings['colspan']);
							$cells++;
						}
						//if colspan IS set to 0, and it's the only cell in the row, set cell count
						//to NULL (later used by $this->find_diff to let it know NOT to adjust
						//the number of cells in this row) 
						else{$cells = NULL;}
					}
					//If there is no colspan set, increment the cell count ($cells)
					else{$cells++;}

					//If there is a rowspan set, compensate
					if(isset($cell->settings['rowspan'])){
						//for each row that is spaned, add 1 or the colspan to an array...later
						//used to adjust the next rows.
						for($i=0;$i<$cell->settings['rowspan']-1;$i++){
							if(isset($cols_from_rowspan[$i])){
								if(isset($cell->settings['colspan'])){$cols_from_rowspan[$i] += $cell->settings['colspan'];}
								else{$cols_from_rowspan[$i]++;}
							}
							else{
								if(isset($cell->settings['colspan'])){$cols_from_rowspan[$i] = $cell->settings['colspan'];}
								else{$cols_from_rowspan[$i] = 1;}
							}
						}
					}
				}
				//Set the col_count for the current group, for the current row to the number
				//of cells in this row
				$col_count[$key][] = $cells;

				//if the number of cells in this row is more than previous rows, adjust the
				//table's number of columns
				if($cells > $this->num_cols){$this->num_cols = $cells;}

				if($row->restart_colors){$color = 0;}

				//if there is no background color for the row, use the next row color in sequence
				if(!preg_match('/background-color:#[0-9A-F]{6}/',$row->settings['style']) && isset($this->row_colors)){
					if(!isset($row->settings['style'])){$row->settings['style'] = '';}
					$row->settings['style'] .= "background-color:{$this->row_colors[$color%sizeof($this->row_colors)]};";
				}
				//increment to next color
				$color++;
			}
		}
		//step through the column counts from each row group
		foreach($col_count as $array => $cur_col_count){
			//change the array of cells per row into an array of numbers of cells to be
			//added to each row to fix the table.
			array_walk($cur_col_count,array($this,'find_diff'));

			//remove any rows that do NOT need any adjustment
			$cur_col_count = array_diff($cur_col_count,array(0));

			//adjust rows, by adding cells
			foreach($cur_col_count as $key => $diff){
				for($i=0;$i<$diff;$i++){
					$this->{$array}[$key]->add_cell();
				}
			}
		}
	}
}
?>
Return current item: PHP HTMLTables