Separating Logic/Style in PHP properly


Answers

Just use some template engine.
The most familiar one is PHP itself.

here is the very basic example of CRUD application:
the logic part doing only data manipulation

<?  
mysql_connect(); 
mysql_select_db("new"); 
$table = "test"; 
if($_SERVER['REQUEST_METHOD']=='POST') { //form handler part: 
  $name = mysql_real_escape_string($_POST['name']); 
  if ($id = intval($_POST['id'])) { 
    $query="UPDATE $table SET name='$name' WHERE id=$id"; 
  } else { 
    $query="INSERT INTO $table SET name='$name'"; 
  } 
  mysql_query($query) or trigger_error(mysql_error()." in ".$query); 
  header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);  
  exit;  
}  
if (!isset($_GET['id'])) { //listing part: 
  $LIST=array(); 
  $query="SELECT * FROM $table";  
  $res=mysql_query($query); 
  while($row=mysql_fetch_assoc($res)) $LIST[]=$row; 
  include 'list.php'; 
} else { // form displaying part: 
  if ($id=intval($_GET['id'])) { 
    $query="SELECT * FROM $table WHERE id=$id";  
    $res=mysql_query($query); 
    $row=mysql_fetch_assoc($res); 
    foreach ($row as $k => $v) $row[$k]=htmlspecialchars($v); 
  } else { 
    $row['name']=''; 
    $row['id']=0; 
  } 
  include 'form.php'; 
}  
?>

and two simple templates responsible for output,
form.php

<? include TPL_TOP ?>
<form method="POST">
<input type="text" name="name" value="<?=$row['name']?>"><br>
<input type="hidden" name="id" value="<?=$row['id']?>">
<input type="submit"><br>
<a href="?">Return to the list</a>
</form>
<? include TPL_BOTTOM ?>

and list.php

<? include TPL_TOP ?>
<a href="?id=0">Add item</a>
<? foreach ($LIST as $row): ?>
<li><a href="?id=<?=$row['id']?>"><?=$row['name']?></a>
<? endforeach ?>
<? include TPL_BOTTOM ?>

Though there are plenty of other template engines, of different kinds and ideologies.

Question

I'm just wondering what is the best way to separate logic components from the layout in a PHP web project?

The content is stored in MySQL, the logic is PHP and the templates are HTML/CSS of course. My question is, how to solve this issue best (without using a CMS).

greetz, poeschlorn




Yes, you do have to reconnect to the database for every pageload. Just put that code in a separate file and use PHP's require_once() function to include it.

Another problem you're having is that the variables $loginemail and $loginpassword would not exist in main.php. You are storing the user's e-mail address in the $_SESSION array, so just reload the user's info:

$safe_email = mysql_real_escape_string($_SESSION['loginemail']);
$result = mysql_query("SELECT * FROM Members
  WHERE fldEmail='$safe_email'");

Also, your code allows SQL Injection attacks. Before inserting any variable into an SQL query, always use the mysql_real_escape_string() function and wrap the variable in quotes (as in the snippet above).




How to echo out info from MySQL table in PHP when sessions are being used.

Will I have to connect again just like I did in login.php?

Yes. This is the way PHP and mysql works

or is there another way I can simply echo out the user's name from the MySQL table?

No. To get something from mysql table you have to connect first.
You can put connect statement into some config file and include it into all your scripts.

How can I echo out the user's fullname which is stored in 'fldFullName' column in MySQL on main.php?

You will need some identifier to get proper row from database. email may work but it's strongly recommended to use autoincrement id field instead, which to be stored in the session.
And at this moment you don't have no $loginemail nor $loginpassword in your latter code snippet, do you?

And some notes on your code

  1. any header("Location: "); statement must be followed by exit;. Or there would be no protection at all.

  2. Any data you're going to put into query in quotes, must be escaped with mysql_real_escape_string() function. No exceptions.

so, it going to be like this

include $_SERVER['DOCUMENT_ROOT']."/dbconn.php";

$loginemail = $_POST['loginemail'];     
$loginpassword = md5($_POST['loginpassword']);  

$loginemail = mysql_real_escape_string($loginemail);     
$loginpassword = mysql_real_escape_string($loginpassword);  

$query = "SELECT * FROM Members WHERE fldEmail='$loginemail' and Password='$loginpassword'";
$result = mysql_query($query) or trigger_error(mysql_error().$query);

if($row = mysql_fetch_assoc($result)) {  
  session_start();  
  $_SESSION['userid'] = $row['id']; // store session data  
  header("Location: main.php"); 
  exit;
} 

and main.php part

session_start();
if(!$_SESSION['userid']) {
  header("Location: index.php"); 
  exit;
} 
include $_SERVER['DOCUMENT_ROOT']."/dbconn.php";

$sess_userid = mysql_real_escape_string($_SESSION['userid']);
$query  = "SELECT * FROM Members  WHERE id='$sess_userid'";  
$result = mysql_query($query) or trigger_error(mysql_error().$query);
$row = mysql_fetch_assoc($result));

include 'template.php';



Prevent user to use back button with warning or disable any insert

Instead of giving link to a third page, redirect to the very same URI
this is quite handy method called POST/Redirect/GET:
here is a concise example of it:

<?php  
if ($_SERVER['REQUEST_METHOD']=='POST') {  

  $err = array();
  //performing all validations and raising corresponding errors
  if (empty($_POST['name'])) $err[] = "Username field is required";  
  if (empty($_POST['text'])) $err[] = "Comments field is required";  

  if (!$err) {  
    //if no errors - saving data and redirect
    header("Location: ".$_SERVER['PHP_SELF']);
    exit;
  }  else {
    // all field values should be escaped according to HTML standard
    foreach ($_POST as $key => $val) {
      $form[$key] = htmlspecialchars($val);
    }
  }
} else {
  $form['name'] = $form['comments'] = '';  
}
include 'form.tpl.php';
?>  

Here you can see another example, concise yet powerful: Separating Logic/Style in PHP properly
it's complete solution to display, add and edit database contents, exactly for admin purpose.




If you just want a good online course, maybe you should have a look at

http://www.lynda.com/home/DisplayCourse.aspx?lpk2=653&srchtrk=index%3A1%0Alinktypeid%3A2%0Aq%3APHP%20Object%20Oriented%0Apage%3A1%0As%3Arelevance%0Asa%3Atrue%0Aproducttypeid%3A2%0Acategory_facet%3APHP

This course was really useful for a friend of me. The progress he booked when he finished this tutorial was really great. It takes you through the basics of building a CMS in PHP and object oriented.






Tags