I am trying to keep all the PHP files separated from the HTML files. Sort of a template based project but without using any template engines as they ar
In index.php
<?php
$query = "SELECT id FROM products ORDER by id";
$product_list = "";
if ($stmt = mysqli_prepare($db_conx, $query)) {
/* execute statement */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $id);
/* fetch values */
}
define("PRODUCT_NAME",$row["product_name"]);
define("PRODUCT_ID",$row["id"]);
define("PRODUCT_PRICE",$row["price"]);
define("PRODUCT_SHIPPING",$row["shipping"]);
define("PRODUCT_CATEGORY",$row["category"]);
?>
<?php include "template.php"; ?>
and in template.php
<html>
<head>
</head>
<body>
<div class='prod_box'>
<div class='center_prod_box'>
<div class='product_title'><a href='#'><?=PRODUCT_NAME?></a></div>
<div class='product_img'><a href='#'><img src='images/<?=PRODUCT_ID?>/Image1.jpg' alt='' border='0' /></a></div>
<div class='prod_price'><span class='reduce'>350$</span> <span class='price'>270$</span></div>
</div>
<div class='prod_details_tab'> <a href='#' class='prod_buy'>Add to Cart</a> <a href='#' class='prod_details'>Details</a> </div>
</div>
</body>
</html>
Your code is a bit of a mess, you need to go back to the basics: your statement is returning $id
and not $product
as you mentioned. To return anything from the database, in your template.html
do:
<html>
<body>
<!-- More html here ... -->
<div class='product_title'>
<!-- Return value like this -->
<a href='#'><?php echo $product_name; ?></a>
</div>
</body>
</html>
Make sure you check the value exists first.
You need to use the extract() function in PHP to get this sorted out. It will then start working as a Controller - View architecture that you are looking for.
For example:
<?php
$query = "SELECT id FROM products ORDER by id";
$product_list = "";
if ($stmt = mysqli_prepare($db_conx, $query)) {
/* execute statement */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $id);
/* fetch values */
while (mysqli_stmt_fetch($stmt)) {
$product_list .= "";
}
}
$data['product_list'] = $product_list;
$view = 'template.php';
loadTemplate($view, $data);
function loadTemplate($view, $data)
{
extract($data);
include($template);
}
?>
Then directly use $product_list
in the view section. This should do it.
Working example:
<?php
$data['test'] = 'This is a working example';
$view = 'workingExampleView.php';
loadTemplate($view,$data);
function loadTemplate($viewName,$viewData)
{
extract($viewData);
include($viewName);
}
?>
Create a new File naming it workingExampleView.php:
<html>
<body>
<span><?php echo $test; ?></span>
</body>
</html>
I would suggest using a template system to parse your template file.
Just something quick and dirty:
class Example {
// This will be used to save all the variables set trough the set() function within the class as an array
private $variables = array();
function set($name,$value) {
// Here we are going to put the key and value in the variables array
$this->variables[$name] = $value;
}
function Template($file) {
// First set the file path of the template, the filename comes from the Template({filename}) function.
$file = '/templates/'.$file.'.php';
// Here we are going to extract our array, every key will be a variable from here!
extract($this->variables);
// Check if it is actually a file
if (!is_file($file)) {
throw new Exception("$file not found");
// Check if the file is readable
} elseif(!is_readable($file)) {
throw new Exception("No access to $file");
} else {
// if both are fine we are going to include the template file :)
include($file);
}
}
}
and use it like this:
$class = new Example;
$class->set("data", $data);
// like passing a name:
$class->set("user", $username);
$class->Template("filename");
Then in your template file you can use $data
and $user
with their contents.
Also, in your template file you're not displaying the variable because it's not in between of PHP tags. Here's two examples for you, one short and the other in the normal format:
<?=$productname?>
// or :
<?php echo $productname; ?>
Oh, and you actually do nothing here:
while (mysqli_stmt_fetch($stmt)) {
$product_list .= "
}
}
You NEED to close the opening "
with ";
and nothing is added to $product_list
.
Honestly, you should use a template system. If you don't want to hinder with learning how they work, there is a very easy approach: create a very simple one yourself. You'll need it sooner or later. The below solution should be very easy, and it's copy-pasteable.
The basic operation of such system is that you:
An example class that is very easy to comprehend might be this:
class HtmlPage
{
private $html;
# Loads specified template file into $html
public function Load($template)
{
if (!file_exists($template)) {
echo "Specified template ($template) does not exist.";
return false;
}
$this->html = file_get_contents($template);
return true;
}
# Takes in an array of data, key is the placeholder replaced, value is the new text
public function Process($data_array)
{
if (!is_array($data_array)) return;
foreach ($data_array as $search => $replace)
{
# Add brackets so they don't have to be manually typed out when calling HtmlPage::Process()
$search = "{$search}";
$this->html = str_replace($search, $replace, $this->html);
}
}
# Returns the page
public function GetHtml()
{
return $this->html;
}
}
Can be used as:
$page_title = "My fancy page title";
$page_text = "All your base are belong to us.";
$page = new HtmlPage();
$page->Load('html/templates/mypage.html');
$page->Process(array(
'TITLE' => $page_title,
'TEXT' => $page_text
));
echo $page->GetHtml();
The above code will replace
<html>
<head>
{TITLE}
</head>
<body>
<p>{TEXT}</p>
</body>
</html>
...to...
<html>
<head>
My fancy page title
</head>
<body>
<p>All your base are belong to us.</p>
</body>
</html>
In your case, this will work like the following:
html/templates/product-item.html:
<div class='prod_box'>
<div class='center_prod_box'>
<div class='product_title'>
<a href='#'>{PRODUCT_NAME}</a>
</div>
<div class='product_img'>
<a href='#'><img src='images/{PRODUCT_ID}/Image1.jpg' alt='' border='0' /></a>
</div>
<div class='prod_price'>
<span class='reduce'>{PRODUCT_PRICE_REDUCE}</span> <span class='price'>{PRODUCT_PRICE}</span>
</div>
</div>
<div class='prod_details_tab'>
<a href='#' class='prod_buy'>Add to Cart</a> <a href='#' class='prod_details'>Details</a>
</div>
</div>
PHP code:
<?php
$query = "SELECT * FROM products ORDER by id";
$product_list = "";
if ($stmt = mysqli_prepare($db_conx, $query))
{
/* execute statement */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $id);
/* fetch values */
$result = mysqli_stmt_get_result($stmt);
while ($product = mysqli_fetch_array($result)) {
$product_html = new HtmlPage();
$product_html->Load('html/templates/product-list.html');
$product_html->Process(array(
'PRODUCT_NAME' => $product['name'];
'PRODUCT_ID' => $product['id'];
'PRODUCT_PRICE' => $product['price'];
'PRODUCT_PRICE_REDUCE' => $product['price_reduce'];
));
$product_list .= $product_html->GetHtml();
}
}