how to separate php code from interface?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
hannnndy
Forum Contributor
Posts: 131
Joined: Sat Jan 12, 2008 2:09 am
Location: Iran>Tehran
Contact:

how to separate php code from interface?

Post by hannnndy »

~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: Posting Code in the Forums to learn how to do it too.


hi,

I'm using php classes to implement the pages but the is always a problem how to separate html and php code

I'm using functions that contains the interface and the functions containing pure php code

have you any better idea?

php code :

Code: Select all

function echoo($str)
{
    echo($str);
}
interface code:

Code: Select all

function echoo($str)
{
?>
<p>echo($str);</p>
<form></form>
<?
}

~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: Posting Code in the Forums to learn how to do it too.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: how to separate php code from interface?

Post by alex.barylski »

Template engines...

Google bTemplate or Smarty.
User avatar
hannnndy
Forum Contributor
Posts: 131
Joined: Sat Jan 12, 2008 2:09 am
Location: Iran>Tehran
Contact:

Re: how to separate php code from interface?

Post by hannnndy »

I mean a logical way because I don't wanna use pre defined classes like smarty because they are complex and too much for medium sites

have you all any idea to separate them using different classes using same parent class or even using functions or something like that?

thanks
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: how to separate php code from interface?

Post by Chris Corbyn »

Logically, the simplest way is to run two processes:

1) Generate data values to be displayed (arrays, numbers, usernames, whatever....)
2) include() a .php file which makes use of those values

Imagine displaying a list of users:

Generate data

Code: Select all

$userList = array(); //For the template
$sql = 'SELECT userid, username FROM users';
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
  $userList[$row['userid']] = $row['username'];
}
 
include('some-template.php');
 

Code: Select all

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Username</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($userList as $userid => $username): ?>
    <tr>
      <td><?php echo $userid; ?></td>
      <td><?php echo $username; ?></td>
    </tr>
    <?php endforeach; ?>
</table>
This is the *very* basic logic involved. To take it a step further and clean things up a bit you'd encapsulate those two concerns (generating model data, and displaying a template) into two different components.

At a really basic level that could just be two functions:

Code: Select all

function get_users()
{
  $userList = array(); //For the template
  $sql = 'SELECT userid, username FROM users';
  $result = mysql_query($sql);
  while ($row = mysql_fetch_assoc($result))
  {
    $userList[$row['userid']] = $row['username'];
  }
  //Return data for the template
  return array('userList' => $userList);
}
 
function include_template($path, $_data = array())
{
  foreach ($_data as $_k => $_v)
  {
    $$_k = $_v; //Create variable-variables (see php.net)
  }
  include($path);
}
Now you can have one place where you pull those two together.

Code: Select all

$modelData = get_users();
include_template('some-template.php', $modelData);
Taking it a step further you'd move away from using those functions and start creating classes... and so on...
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: how to separate php code from interface?

Post by thinsoldier »

Chris Corbyn wrote:Taking it a step further you'd move away from using those functions and start creating classes... and so on...
which is where I think I'm at right now.... no idea if I'm doing it in a good way.

what do you think?

Code: Select all

 <?
require_once('config.php');
 
//-------
// Data
//-------
// gather FAQ data to be placed in content column later
$sql = "SELECT DISTINCT faqcat FROM faq order by faqcat ASC";
$result = mysql_query($sql) or die(mysql_error());
while($data = mysql_fetch_assoc($result))
{ $faqcats[] = $data['faqcat']; }
 
 
$BODY = '';
$questions = '';
 
foreach($faqcats as $category)
{
    $BODY .= '<h2>'.$category.'</h2>';
    
    $sql = "SELECT * FROM faq WHERE faqcat='$category'";
    $result = mysql_query($sql) or die(mysql_error());
    
    while($qqq = mysql_fetch_assoc($result))
    {  
        $format = '<li><a href="%s?answer=%s">Q: %s</li>';
        $questions .= '<ul>'.sprintf($format, thispage(), $qqq['id'], $qqq['headline']).'</ul>';
    }
    $BODY .= $questions;
}
 
 
 
//----------
// Display
//----------
$p = new SitePage;
 
$p->Col_content = $BODY;
 
//HTMLHead is created within the page object
$p->Head->PrefixTitle('Frequently Asked Questions - ');
$p->Head->LinkCSS('scripts/faq.css');
$p->Head->LinkJS('scripts/control.tabs.2.1.1.js');
 
// select which items in the navigation array
// should be set to class=active
$p->SelectTopNav('About Us'); 
$p->SelectSubNav('FAQ');
 
// nothing in left column on this page
//$p->Col_a = '';
 
 
// by default col_b is  Member sign in, and contact boxes
// usually you'd concatenate other boxes BEFORE these 
// nothing special goin in side column of about area page
// so leave the default
// $p->Col_b = 'something.$p->Col_b';
 
echo $p->Output();
?> 
User avatar
hannnndy
Forum Contributor
Posts: 131
Joined: Sat Jan 12, 2008 2:09 am
Location: Iran>Tehran
Contact:

Re: how to separate php code from interface?

Post by hannnndy »

Thanks for reply

I have done that before and changed my functions into classes and to some extends it was successful
but the problem is : To customizing the pages classes and to mentioning the forms and so on

you know i have no idea how to create classes for forms of other html elements in classes

have you any idea for interface elements like html elements and forms too?
User avatar
dbevfat
Forum Contributor
Posts: 126
Joined: Tue Jun 28, 2005 2:47 pm
Location: Ljubljana, Slovenia

Re: how to separate php code from interface?

Post by dbevfat »

hannnndy wrote:I'm using php classes to implement the pages but the is always a problem how to separate html and php code

I'm using functions that contains the interface and the functions containing pure php code
I think you actually want to separate business logic from presentation logic (and not php code from html code). Many solutions were posted already, I just thought I'd nitpick a bit, because I think the difference is important. :)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: how to separate php code from interface?

Post by Chris Corbyn »

~thinsoldier. That approach seems to work for some people but I generally think it's a bad idea to so tightly couple your backend PHP with the layout.... I mean, what if you switched to using a side navigation bar instead of a TopNav and BottomNav? Do you rewrite your view class to deal with it? Followed by a rewrite of the controller which passes data to the view? Better off just setting the required data and loading in a bog standard template, not having to care about the layout or how it will render.
hannnndy wrote:Thanks for reply

I have done that before and changed my functions into classes and to some extends it was successful
but the problem is : To customizing the pages classes and to mentioning the forms and so on

you know i have no idea how to create classes for forms of other html elements in classes

have you any idea for interface elements like html elements and forms too?
Don't try creating HTML using classes. Just load a template file with some very very basic PHP in it like I showed.

A basic view class (just a container pretty much):

Code: Select all

class View {
 
  private $_data = array();
 
  public function setVar($key, $value) {
    $this->_data[$key] = $value;
  }
 
  public function render($_template) {
    foreach ($this->_data as $_k => $_v) {
      $$_k = $_v;
    }
    include $_template;
  }
 
}
A controller:

Code: Select all

class UserController {
 
  private _$view;
  private $_request;
  private $_response;
  
  public function __construct($view, $request, $response) {
    $this->_view = $view;
    $this->_request = $request;
    $this->_response = $response;
  }
 
  public function loginAction() {
    $username = $this->_request->get('username');
    $password = $this->_request->get('password');
    if ($username && $password) {
      //Try logging the user in
      if (!$user = User::findByUsernameAndPassword($username, $password)) {
        $this->_request->getSession()->setActiveUser($user);
        return $this->_response->redirect('/');
      } else {
        $this->_view->setVar('error', 'Invalid username or password');
      }
    }
 
    $this->_view->render('templates/some-template.tpl.php');
  }
 
  public function logoutAction() {
    //whatever
  }
  
}
And some kind of dispatcher (look up the front controller pattern):

Code: Select all

$controller = $request->get('controller');
$action = $request->get('action');
 
$controllerObj = new $controller(new View(), $request, $response);
$controllerObj->$action();
User avatar
hannnndy
Forum Contributor
Posts: 131
Joined: Sat Jan 12, 2008 2:09 am
Location: Iran>Tehran
Contact:

Re: how to separate php code from interface?

Post by hannnndy »

thank you all for the quick replies
I cant understand your idea you mean that I should not use classes for the html codes bud the problem is i cant separate them already

for my present project i just seprate the codes into
interface.php >> containing all forms in php functions and html elements like tables
,
functions.php >> congaing the specific functions for that section and the functions which uses the parent classes
and
a parent directory to put all the classes in it for the child folders to use it
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Re: how to separate php code from interface?

Post by Kieran Huggins »

It would help to look into MVC patterns.

You can have "helpers" that generate HTML code, like input_tag($model->property) to generate an input tag - but those belong in the view.
thinsoldier
Forum Contributor
Posts: 367
Joined: Fri Jul 20, 2007 11:29 am
Contact:

Re: how to separate php code from interface?

Post by thinsoldier »

Chris Corbyn:
TopNav and SubNav don't literraly represent a navigation item at the top or side of a page. They're just arrays of links and titles.

The SitePage class does include() a simple html file(template) by default that defines where the main navigation and sub navigation will be used and uses the contents of TopNav & SubNav to build the navigation and assign the 'active' link.

Any more potential problems you can think up would be great.

... and I've got a ways to go before I start understanding your view,controller,dispatcher examples :(


hannnndy:
The way I show I only "customize" the contents of the 3 columns of my page by dropping plain HTML in there. It really doesn't make sense to use php functions or classes for every possible html tag.

But I have found it useful to have a class for building forms. Not because I'm lazy and don't like writing form field tags but because it helps me keep track of data across submits, pre-populate the fields with data from the database, validate submitted data, generate and display errors to the user...etc.

Trying to make a simple class for the most common form elements is actually a pretty good exercise. You can even incorporate inheritance into it. For example: class field_email extends field_text (adds validation for email addresses automatically)
class field_date extends field_text (adds validation for 6/15/2008 automatically)
Warning: I have no idea what I'm talking about.
RecoilUK
Forum Commoner
Posts: 30
Joined: Sun Feb 29, 2004 7:13 pm

Re: how to separate php code from interface?

Post by RecoilUK »

Hi guys

In an ideal world you could seperate your php code from your html, but in the real world this is impossible.

What I do is just include containers inside the html I want to use, and if I need a loop of some sort then I use a class method to do this along with a template system.

A good use for this is the HEREDOC syntax ...

Code: Select all

<?PHP
 
$html = <<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Strict//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11-strict.dtd">
 
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="cmsstyle.css" />
    <title>$PageVar['title']</title>
  </head>
  <body>        
END;
 
?>
As you can see, this includes very little php and the best thing is, you really dont need a complicated template system because as long as the variable used in the template exists before you include the file, the variable is automatically parsed.

Hope that helps.
mabus
Forum Newbie
Posts: 17
Joined: Wed Apr 16, 2008 11:52 pm

Re: how to separate php code from interface?

Post by mabus »

hannnndy wrote:hi,

I'm using php classes to implement the pages but the is always a problem how to separate html and php code

I'm using functions that contains the interface and the functions containing pure php code

have you any better idea?
I'd also advice you to learn and apply the MVC concept. That is Model-View-Controller approach in creating solutions.
Post Reply