PHP class to output clean HTML

I was looking for a basic lightweight framework for PHP but they all offer more stuff than I need, they make coding too "automatic" for my taste so I decide to write my own classes. This is part 1, I should write in the next days a user class, DB class and some other usefull classes (validation, etc...).

What's the purpose of using this class? Well if you are like me and like having well written/formatted html, this is for you. You can write code the "long way" (clean) or the "short way" (ugly). If you use the short way, you will notice that child nodes are created before parent node so it might be confusing at first.

//LONG
require_once HtmlElement.class.php';
 
//First row, first column
$my_table = new HtmlElement('table');
$my_tr = new HtmlElement('tr', array('class'=>'rowclass'));
$my_td = new HtmlElement('td');
$my_anchor = new HtmlElement('a',array('href'=>'http://google.com','title'=>'Google'));
$my_div = new HtmlElement('div');
$my_image = new HtmlElement('img',array('src'=>'http://www.google.ca/intl/en_ca/images/logo.gif', 'border'=>'0'));
$my_input = new HtmlElement('input', array('type'=>'hidden'));
 
$my_div->inject(array($my_image));
$my_anchor->inject(array($my_div));
$my_td->inject(array($my_anchor,$my_input));
$my_tr->inject(array($my_td));
 
//Second row
$my_tr2 = new HtmlElement('tr', array('class'=>'rowclass'));
 
//Second row, first column
$my_td = new HtmlElement('td');
$my_p = new HtmlElement('p', '', '', 'Please select an option : ');
$my_td->inject(array($my_p));
 
//Second row, second column
$my_td2 = new HtmlElement('td');
$my_select = new HtmlElement('select');
for($i=0;$i<=10;$i++){
  $my_options[] = new HtmlElement('option',array('value'=>$i),'','Option' . $i);
}
$my_select->inject($my_options);
$my_td2->inject(array($my_select));
 
$my_tr2->inject(array($my_td,$my_td2));
 
//Create the table and output
$my_table->inject(array($my_tr,$my_tr2));
$my_table->output();

Is equivalent to :

//SHORT
<?php
require_once HtmlElement.class.php';
 
//Create a column on the first row
$my_image = new HtmlElement('img',array('src'=>'http://www.google.ca/intl/en_ca/images/logo.gif', 'border'=>'0'));
$my_div = new HtmlElement('div', '', array($my_image));
$my_anchor = new HtmlElement('a',array('href'=>'http://google.com','title'=>'Google'),array($my_div));
$my_input = new HtmlElement('input', array('type'=>'hidden'));
$my_td = new HtmlElement('td', '', array($my_anchor, $my_input));
 
//Create the first row
$my_tr = new HtmlElement('tr', array('class'=>'rowclass'), array($my_td));
 
//Create a column on the second row
$my_p = new HtmlElement('p', '', '', 'Please select an option : ');
$my_td = new HtmlElement('td', '', array($my_p));
 
//Create a second column on the second row
for($i=0;$i<=10;$i++){
  $my_options[] = new HtmlElement('option',array('value'=>$i),'','Option' . $i);
}
$my_select = new HtmlElement('select','',$my_options);
$my_td2 = new HtmlElement('td', '', array($my_select));
 
//Create a second row
$my_tr2 = new HtmlElement('tr', array('class'=>'rowclass'), array($my_td, $my_td2));
 
//Create the table and output
$my_table = new HtmlElement('table', '', array($my_tr, $my_tr2));
$my_table->output();

Both would output clean HTML like :

<table>
  <tr class="rowclass">
    <td>
      <a href="http://google.com" title="Google">
        <div>
          <img src="http://www.google.ca/intl/en_ca/images/logo.gif" border="0" />
        </div>
      </a>
      <input type="hidden" />
    </td>
  </tr>
  <tr class="rowclass">
    <td>
      <p>Please select an option : </p>
    </td>
    <td>
      <select>
        <option value="0">Option0</option>
        <option value="1">Option1</option>
        <option value="2">Option2</option>
        <option value="3">Option3</option>
        <option value="4">Option4</option>
        <option value="5">Option5</option>
        <option value="6">Option6</option>
        <option value="7">Option7</option>
        <option value="8">Option8</option>
        <option value="9">Option9</option>
        <option value="10">Option10</option>
      </select>
    </td>
  </tr>
</table>

Here is the full class, please let me know if you see any problems :

<?php
  /**
  * HtmlElement.class.php
  * This is a PHP class for generating HTML
  * @version 1.1
  * @author Marc-Andre Caron - http://www.blogama.org
  * @license http://www.gnu.org/copyleft/lesser.html LGPL
  */
class HtmlElement
{
  //------------------------------------------------------------
  // PROPERTIES
  //------------------------------------------------------------
 
  //--Protected properties--//
 
  /**
  * @var tag type
  * @access protected
  */
  protected $_type;
 
  /**
  * @var tag attributes
  * @access protected
  */
  protected $_attributes;
 
  /**
  * @var tag text
  * @access protected
  */
  protected $_text = false;
 
  /**
  * @var tag closers
  * @access protected
  */
  protected $_self_closers = array('input','img','hr','br','meta','link');
 
  //------------------------------------------------------------
  // METHODS
  //------------------------------------------------------------
 
  //--Public methods--//
 
  /**
  * This is the class constructor. 
  * It allows to set up the tag type, attributes, childs and text
  * @param string $type Tag type
  * @param array $attribute Tag type
  * @param array $objects Tag type
  * @param string $text Tag type
  * @access public
  */
  public function __construct($type, $attribute = '', $objects = '', $text = '') {
    //Set the type
    $this->_type = strtolower($type);
    $this->_attributes = array();
 
    //Set attributes
    if (is_array($attribute)) $this->setAttributes($attribute);
 
    //Inject HTML into parent
    if (is_array($objects)) $this->inject($objects);
 
    //Set tag text
    if ($text) $this->setText($text);
  }
 
  /**
  * Returns the value of an attribute
  * @param string $attribute
  * @access public
  */
  public function getAttributes($attribute) {
    return $this->_attributes[$attribute];
  }
 
  /**
  * Set the value of an attribute
  * @param array $attribute_arr
  * @access public
  */
  public function setAttributes($attribute_arr) {
    $this->_attributes = array_merge($this->_attributes,$attribute_arr);
  }
 
  /**
  * Set the text between opening and closing tag
  * Tag must be text only
  * @param string $attribute
  * @param string $value
  * @access public
  */
  public function setText($text) {
    if (is_string($text)) {
      $this->_text = $text;
    }
  }
 
  /**
  * Remove an attribute
  * @param string $attribute
  * @access public
  */
  public function remove($attribute) {
    if (isset($this->_attributes[$attribute])) unset($this->_attributes[$attribute]);
  }
 
  /**
  * Clear all attributes
  * @access public
  */
  public function clear() {
    $this->_attributes = array();
  }
 
  /**
  * Insert an array of child nodes into parent.
  * Format code with an indent of 2 whitespace for childs nodes
  * @param array $object_arr
  * @access public
  */
  public function inject($object_arr) {
    foreach ($object_arr as $object) {
      if (get_class($object) == get_class($this)) {
        $object->_attributes['text'] = str_replace("  <","    <",$object->_attributes['text']);
        $this->_attributes['text'] .= "  ";
        $this->_attributes['text'] .= str_replace(">\n<", ">\n  <", $object->build());
      }
    }
  }
 
  /**
  * Print the html
  * @access public
  */
  public function output() {
    echo $this->build();
  }
 
  //--Protected methods--//
 
  /**
  * Build the HTML node
  * @access protected
  */
  protected function build() {
    //start
    $build = '<' . $this->_type;
 
    //add attributes
    if (count($this->_attributes)) {
      foreach ($this->_attributes as $key=>$value){
        if ($key != 'text') $build .= ' ' . $key . '="' . $value . '"';
      }
    }
 
    //closing
    if (!in_array($this->_type,$this->_self_closers)) {
      //Parent node cannot have text
      if (is_string($this->_text)) {
        $build .= ">" . $this->_text . '</' . $this->_type . ">\n";
      } else {
        $build .= ">\n" . $this->_attributes['text'] . '</' . $this->_type . ">\n";
      }
    } else {
      $build .= " />\n";
    }
 
    //return it
    return $build;
  }
}