Jump to content

HTML Objects

- - - - -

  • Please log in to reply
6 replies to this topic

#1
BlaineSch

BlaineSch

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,448 posts
So I've recently been complaining a lot about my "not so clean" looking PHP code due to HTML. I made an example below of how ugly it can look. This is untested since I just wrote it, but it gets my point across.

I recently created a "HTML Element" object which I can use to create any object while setting basically any attribute. I then made a "Table Creator" object which I used for creating tables since I realized that would still be messy with all those weird items.

One of old bookmarks recently came into play again which was phpQuery which let's you do some pretty neat things with HTML on the server side.

What is your opinion on these types of things? Know any tricks? See any downfalls?

<?PHP
// This would look a ton neater without ugly HTML clogging up it's arteries.
class userData {
    private $id;
    private $link;
    public function __construct($link) {
        $this->id = mt_rand(0,9);
        $this->link = $link;
    }
    public function displayUser($uid) {
        $rows = getUserInfo($uid);
        if($rows===false) {
?>
    <div class="banner error">
        <h3>Error!</h3>
        <p>This user does not exist!</p>
    </div>
<?PHP
        } else {
?>
    <div class="banner user">
        <div class="el">
            <div class="key">Username</div>
            <div class="value"><?=$row['username']?></div>
        </div>
    </div>
<?PHP
        }
    }
    private function getUserInfo($uid) {
        $query = mysql_query("SELECT * FROM `users` WHERE `id`={$uid} LIMIT 1", $this->link);
        if(mysql_num_rows($query)==0) {
            return false;
        }
        return mysql_fetch_assoc($query);
    }
}
<?PHP
/*
    Generates HTML characters
    Example #1:
        $link = new HTMLElement('a');         //set name using constructor
        $span = new HTMLElement();             //just declare a new element
        $link->href = "index.html";            //set an attribute
        $link->class = "ref";                 //set a second attribute
        $link->innerHTML = $span;             //PHP passes objects by reference
        $span->name = "span";                 //set name since not declared earlier
        $span->innerHTML = "Hello world";     //declare an attribute
        echo $link->generate();             //generate my link
    Output #1:
        <a href="index.html" class="ref"><span>Hello world</span></a>
    Example #2:
        $table = new HTMLElement('table');
        $row = new HTMLElement('tr');
        $cell = new HTMLElement('td');

        $cell->innerHTML = "1";
        $table->innerHTML = $row;
        $row->innerHTML = $cell;

        $cell = new HTMLElement('td');         //disowns last object and creates new one
                                            //I cannot edit the first cell anymore
        $cell->innerHTML = "2";
        $row->innerHTML = $cell;

        echo $table->generate();
    Output #2: (I Added formatting)
        <table>
            <tr>
                <td>1</td>
                <td>2</td>
            </tr>
        </table>
    Functions:
        public: 
            __construct([Element Name]); 
                Sets up the elemnt, can be used later using set("name",...)
            __set([$key], [$value]), $obj->key = value;
                Sets attribute keys and values
                NOTE:
                    This always appends. Edit the object you have, but you can NEVER edit this data.
            generate()
                Generates the HTML output.
            selfEnding(boolean)
                If you want to over write the existing selfEnding for a tag that may be both
        private:
            setName($name)
                Sets the name and attempts to figure out if this is a self ending tag or not
*/
class HTMLElement {
    private $name;
    private $attr = array();
    private $selfEndingList = array('area', 'base', 'basefront', 'br', 'col', 'frame', 'hr', 'img', 'input', 'link', 'meta', 'param', 'script');
    private $selfEnding;
    private $innerHTML = array();
    public function __construct($name = false, $data = false) {
        /*
            <{name} {attrs} [/>] OR [>{innerHTML}</{name}>]
        */
        if($name !== false) {$this->setName($name);}
        if($data !== false) {$this->__set('innerHTML', $data);}
    }
    private function setName($name) {
        $this->name = $name;
        $this->selfEnding = false;
        if(in_array($this->name, $this->selfEndingList)) {
            //automatically assigned
            $this->selfEnding = true;
        }
    }
    public function selfEnding($bool) {
        /*
            Some are self ending and non-self ending. So a way to over write this automatic feature is included
            Example:
                <script src="scripts.js" type="text/javascript" />
                <script type="text/javascript">alert('Hello World');</script>
        */
        $this->selfEnding = $bool;
    }
    public function __set($key, $value) {
        /*
            Setting function to set attributes
            Example
                $obj->src = "image.jpg";
        */
        if($key=="innerHTML") {
            $this->innerHTML[] = $value;
            return;
        } else if($key=="name") {
            $this->setName($value);
            return;
        }
        $this->attr[$key] = $value;
    }
    public function generate() {
        /*
            Creates the tag and returns it
        */
        $attrs = "";
        foreach($this->attr AS $key=>$value) {
            //generates the attributes
            $value = str_replace('"', '\"', $value);
            $attrs .= " {$key}=\"{$value}\"";
        }
        if(in_array($this->name, $this->selfEndingList)) {
            //self ending tag, no innerHTML
            return "<{$this->name}{$attrs}/>";
        } else {
            //non self ending tags
            foreach($this->innerHTML as $data) {
                if(is_object($data)) {
                    //it is an HTMLElement object generate the data
                    //print_r($data);
                    $ex .= $data->generate();
                } else {
                    $ex .= $data;
                }
            }
            return "<{$this->name}{$attrs}>{$ex}</{$this->name}>";
        }
    }
}
<?PHP
/*
    Even with the HTMLElement Class it can still get messy making tables. This is the solution.
    Example:
        $table = new tableBuilder(array('cellpadding'=>'0', 'class'=>'calendar'));
        $table->addRow();
        $table->addCell('1', array('colspan'=>'2'));
        $table->addRow();
        $table->addCell('2');
        $table->addCell('3');
        echo $table->getTable();
    Output: (Manually Formatted)
        <table cellpadding="0" class="calendar">
            <tr>
                <td colspan="2">1</td>
            </tr>
            <tr>
                <td>2</td>
                <td>3</td>
            </tr>
        </table>
        
*/
include_once('HTMLElement.obj.php');
class tableBuilder {
    private $table;
    private $row;
    private $cell;
    public function __construct($extra = array()) {
        $this->startTable($extra);
    }
    public function startTable($extra = array()) {
        $this->table = new HTMLElement('table');
        foreach($extra as $key=>$value) {
            $this->table->$key = $value;
        }
    }
    public function addRow($extra = array()) {
        //starts a new row
        $this->row = new HTMLElement('tr');
        $this->table->innerHTML = $this->row;
        foreach($extra as $key=>$value) {
            $this->row->$key = $value;
        }
    }
    public function addCell($data, $extra = array()) {
        $this->cell = new HTMLElement('td');
        $this->cell->innerHTML = $data;
        foreach($extra as $key=>$value) {
            $this->cell->$key = $value;
        }
        $this->row->innerHTML = $this->cell;
    }
    public function getTable() {
        return $this->table->generate();
    }
}


#2
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts
  • Location:New York, NY
Yuck. Business logic, data, and page structure in the same file. You are right, that code is horrid. You should really consider employing an MVC structure, it will clean up your code a lot. As for using something like that, I think its retarded, an unnecessary abstraction, and an abuse of OOP. You end up using extra resources (memory and processor cycles) and you over complicate your code.

Note: As I read that over, my tone sounds sounds more harsh than I intended it to be. It was meant to be constructive criticism, not insulting. :)

#3
BlaineSch

BlaineSch

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,448 posts
I see your point with the MVC and have downloaded some example code to play around with. I really do appreciate the tip. Nobody ever stops learning, however I feel knowing this years ago would have made life easier.

The phpQuery I had mentioned is rather handy. I've never done benchmarking on it, but for data mining which I do a ton of it's very helpful. Since I can use jQuery selectors (mostly) I can do server side data mining.

However if you can think of an alternative that would be great. My boss right now is wanting me to make a data miner that would run daily to cache post count on various accounts and websites for statistical purposes.

<?PHP
require_once('../phpQuery/phpQuery.php');

//$doc = phpQuery::newDocumentFile('http://forum.codecall.net/members/plogen.html'); // 1 post
$doc = phpQuery::newDocumentFile('http://forum.codecall.net/members/john.html'); // 6,001 posts

$posts = $doc->find('#view-statistics')->next();

print $posts->find('dl.stats:eq(0) dt')->html(); // Outputs: Total Posts (just for visual validation)
print $posts->find('dl.stats:eq(0) dd')->html(); //Outputs: 1 OR 6,001 (actual post count)


#4
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts
  • Location:New York, NY
Ah, for data mining, that looks like it could be pretty powerful. I haven't done much of that, so I really can't provide any valuable input, but I would assume PHP's DOM functions (PHP: DOM - Manual) could do this too, perhaps not as elegantly.

As for MVC, I would HIGHLY recommend watching some of these videos and playing with CodeIgniter:
http://codeigniter.com/tutorials/
http://codeigniter.c...Help::Tutorials

#5
BlaineSch

BlaineSch

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,448 posts
Well, honestly, I've tried to stay away from PHP Frameworks. However the demo looked rather nice, I might download it and a few other (Zend I suppose) and see which ones I like better.

I found it ironic that it has functions that generated HTML that it demonstrated in the demo. :c-lol:

#6
zeroradius

zeroradius

    Speaks fluent binary

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,406 posts
I don't think he means for you to use CodeIgniter to make your sites. CodeIgniter uses MVC very heavily so learning how to use it will give you a glimpse inside of how MVC works. He gave me the same advice when I started learning to use the MVC pattern. Then you can build your own personal framework. There are a lot of things out there on MVC and none of them agree, and a lot of it is wrong. Just remember MVC is a compound pattern it is made up of three other patterns working together (strategy, observer, and composite) . If you have some extra money I recomend this book: Amazon.com: Used and New: Head First Design Patterns . Learning MVC is a battle but the book breaks it down for you extremely well. In the end this pattern is nice to have.
Posted Image

#7
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts
  • Location:New York, NY

zeroradius said:

I don't think he means for you to use CodeIgniter to make your sites. CodeIgniter uses MVC very heavily so learning how to use it will give you a glimpse inside of how MVC works.
That is exactly what I was trying to say. :c-grin:




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users