Just starting OOP... Conversion questions...

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
theda
Forum Contributor
Posts: 332
Joined: Sat Feb 19, 2005 8:35 am
Location: USA

Just starting OOP... Conversion questions...

Post by theda »

Okay, before, I used a ton of get cookie functions and some poorly spliced PHP/HTML hybrid pages to produce my website. Now I have decided (after Jshpro2 suggested it...) to convert it to OO-style. So far it's working pretty nice, and I don't have problems with the majority of the conversion... There is only one thing that currently befuddles me :) (Well there's sure to be more, but this one for now anyway...)

I used isset() conditionals to check if a page is being loaded (?page=someblah)... Now with a template-style system... How do I get pages to load in a similar fashion?

layout template code:

Code: Select all

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>
	<html xmlns='http://www.w3.org/1999/xhtml'>
		<head>
			<title>{title}</title>
			<link rev='made' href='{webmaster}' />			
			<link rel='shortcut icon' type='image/ico' href='{favicon}' />
			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' />	
			<meta name='Description' content='{description}' />
			<meta name='keywords' content='{keywords}' />
			<meta name='author' content='{author}' />
			<meta name='robots' content='all' />
			<base href='{base}' />
			{stylesheet}
		</head>
		<body>
			<div id='box'>
				<div id='head'>
					<p><a href='http://dumbass.ionichost.com'><img src='{banner}' alt='theda' title='theda' width='750' height='150' /></a><a id='top'></a></p>
					<h1>{motto}</div>	
				<div id='left'>
					<h1>{navtitle}</h1>
					{navcontent}
					<h1 style='text-align:center'>[ {language} ]</h1>
					<p style='text-align:center'>{theme}</p>
				</div>
				<div id='content'>
					<h1>{pagetitle} [ {pageupdated} ]</h1>
					{pagecontent}
					<p>&nbsp;</p>
					<p>{pagetop}</p>
				</div>
			
			</div>
		</body>
	</html>
OO-style script:

Code: Select all

<?php
require_once("inc/template.php");

$page = new Page("inc/layout.html");

$page->replace_tags(array(
  "title" => "XXXXXXXXXXXXXXXX",
  "webmaster" => "XXXXXXXXXXXXXXXX",
  "favicon" => "img/favicon.jpg",
  "description" => "inc/description.dat",
  "keywords" => "inc/keywords.dat",
  "author" => "XXXXXXXXXXXXXXXX",
  "base" => "XXXXXXXXXXXXXXXX",
  "stylesheet" => include "include/style".$the.".php",
  "motto" => "inc/motto.dat",
  "navtitle" => "inc/navtitle.dat",
  "navcontent" => "inc/navcontent.dat",
  "language" => "inc/language.dat",
  "theme" => "inc/theme.dat",
  "pagetitle" => "inc/pagetitle.dat",
  "pageupdated" => "inc/pageupdated.dat",
  "pagecontent" => "inc/pagecontent.dat",
  "pagetop" => "inc/pagetop.dat"
));

$page->output();
?>
It doesn't have all of my scripting in it yet, but I haven't gotten around to recoding the cookie setting features (but that really doesn't matter right now).
theda
Forum Contributor
Posts: 332
Joined: Sat Feb 19, 2005 8:35 am
Location: USA

Post by theda »

Oh, sorry, forgot to put the template.php page out:

Code: Select all

<?php
class Page
{
  var $page;

  function Page($template = "inc/layout.html") {
    if (file_exists($template))
      $this->page = join("", file($template));
    else
      die("Template file $template not found.");
  }

  function parse($file) {
    ob_start();
    include($file);
    $buffer = ob_get_contents();
    ob_end_clean();
    return $buffer;
  }

  function replace_tags($tags = array()) {
    if (sizeof($tags) > 0)
      foreach ($tags as $tag => $data) {
        $data = (file_exists($data)) ? $this->parse($data) : $data;
        $this->page = eregi_replace("{" . $tag . "}", $data,
                      $this->page);
        }
    else
      die("No tags designated for replacement.");
  }

  function output() {
    echo $this->page;
  }
}
?>
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I'm sorry, but i have a feeling you are reinventing the wheel here.. http://smarty.php.net.

Btw, i don't see any advantage in the OOP template system? All i see is that you now have overhead replacing the tags..

Here is how i would do it: (the request object is built by the controller.. and contains stuff like which database/activerecord should be shown..)

Code: Select all

<?php

// +---------------------------------------------------------------------------
// | Author: Tim Van Wassenhove <timvw@users.sourceforge.net>
// |
// | This class represents a View.
// +---------------------------------------------------------------------------
// | $Id:$
// +---------------------------------------------------------------------------

class View
{
  var $file;
  var $contenttype;
  
  function View($file, $contenttype = 'text/html')
  {
    $this->file = $file;
    $this->contenttype = $contenttype;
  }
  
  function getBody($request)
  {
    ob_start();
    require_once($this->file);
    $body = ob_get_contents();
    ob_end_clean();
    return $body;
  }
  
  function getHeaders($request)
  {
    $headers = array($this->contenttype);
  }

  
  function getResponse($request)
  {
    $body = $this->getBody($request);
    $headers = $this->getHeaders($request);
    return new Response($body, $headers);
  }
}

?>
And here is a sample "template" file:

Code: Select all

<html>
<head>
<title><?php $request->getValue('title'); ?></title>
</head>
<body>
<table>
<form>
<?php
  $activerecord = $request->getValue('activerecord');
  $rows = $activerecord->read();
  if (!$rows)
  {
    print_r($activerecord->getErrors());
  }
  else
  {
    $columns = $request->getValue('columns');
    echo '<tr>';
    echo '<th>Select</th>';
    $i = 0;
    foreach($columns as $column => $caption)
    {
      echo '<th><a href="?orderby=' . $i . '">' . $caption . '</a></th>';
      ++$i;
    }
    echo '</tr>';
    
    $i = 0;
    $keys = array_keys($columns);
    foreach($rows as $row)
    {
      echo '<tr>';
      echo '<td><input type="checkbox" name="select[]" value="' . $i . '"/></td>';
      foreach($row as $column => $value)
      {
        if (in_array($column, $keys))
        {
          echo '<td>'  . $value . '</td>';
        }
      }
      echo '</tr>';
      ++$i;
    }
  }
?>
</form>
</table>
</body>
</html>
theda
Forum Contributor
Posts: 332
Joined: Sat Feb 19, 2005 8:35 am
Location: USA

Post by theda »

Not to annoy, but ... I have no Tr's, Table's or Form's :)
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

You can still use isset before you stuff it in the array wit tags that need to be replacesd, and you can still use it in your template too..

But if you used it in your template, you would defeat the {name} purpose, so you would have to extend your template by implementing a {name/condition} or whatever construction.. that is why i said i had the feeling you were reinventing the wheel... and gave you a pointer to smarty...

(I don't care about the tags a page has, as long as they are used correctly ;))
x01
Forum Newbie
Posts: 4
Joined: Wed Aug 03, 2005 3:38 pm

Post by x01 »

Smarty is indeed the best PHP Template system out-there, but I think you gave a bad example timvw.

Coders should always separate code from html.

---

theda if you want a good OO template system, follow by timvw and use Smarty. It's simple, *fast*, cache supporte, and has a huge community of support available.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

I feel that PHP is way better template language than smarty.

If you use smarty control structures, you're coding too..

Even if i post my XSLView class, the XSL will contain <xsl:choose> tags which can be considered as coding...

So, please tell me why coders should separate code and html..
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

timvw wrote:I feel that PHP is way better template language than smarty.
Better is definitely subjective, but thats not an unfair statement.
timvw wrote:If you use smarty control structures, you're coding too..
Sure. But there is a difference between model, view, and controller. :)
timvw wrote:So, please tell me why coders should separate code and html..
I think a better statement would be "When it makes sense, coders should try to seperate model, view and controller".

As to why, it allows better flexibility in each segment, more maintainability, a much more specific location for bugs to occur in, easier testing..

The list is really quite long. In a nutshell, it lets you be "cleaner", which in turn makes it easier to code better.

Is it always the right choice? Absolutely not. But when it makes sense, it makes a whole lotta sense.
theda
Forum Contributor
Posts: 332
Joined: Sat Feb 19, 2005 8:35 am
Location: USA

Post by theda »

I don't want smarty. :P I ran across it long before I ever asked questions about OOP...
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Roja wrote: I think a better statement would be "When it makes sense, coders should try to seperate model, view and controller".

As to why, it allows better flexibility in each segment, more maintainability, a much more specific location for bugs to occur in, easier testing..

The list is really quite long. In a nutshell, it lets you be "cleaner", which in turn makes it easier to code better.
I also only posted the basic View class (which indeed retrieves data from the Model/ActiveRecords) The complete architecture looks like: (Except that my View class returns a Response object to the Controller, which knows how to send that back to the client. )

Image

Roja wrote: Is it always the right choice? Absolutely not. But when it makes sense, it makes a whole lotta sense.
I agree that sometimes a quick hack is more suitable (and sometimes plain static html is even better) But for some reason, those little hacks always seem to grow anyway... Thus usually it's better to do it right from the start :)
Post Reply