17

I currently have a very simple page, with some more complicated backend. I've always done this the same way, but I feel it's not right. But I haven't come up with much useful to me.

I've got my index.php, header.php and function.php. index.php includes header.php, which calls a function from function.php. The main thing I'm not sure about is how to make the website dynamic enough that it can have easily editable pages, but also be easily editable is a big part of it needs editing.
index.php

<?php
session_start();
include_once 'header.php';
?>
// Page content
</body>
</html>

header.php

<!DOCTYPE HTML>
<html lan="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<?php
require_once 'functions.php';
getBar(); // Top of page bar with menu/login etc
?>

I don't think showing functions.php would add that much. I know I shouldn't use 2 <head>s in my file, so what do I do if I want to have a description on each page? I've previously had the files setup like: index.php

<?php
session_start();
include_once 'header.php';
?>
// extra page specific stuff here, such as description or JS
</head>
<body>
<?php
require_once 'functions.php';
getBar(); // Top of page bar with menu/login etc
?>
// Page content here
</body>
</html>

header.php

<!DOCTYPE HTML>
<html lan="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" />

However, I think the files are "fragmented". I don't know if there is a generally accepted way of doing this, but if there is, I'd love to hear it!

hakre
  • 193,403
  • 52
  • 435
  • 836
Joseph Duffy
  • 4,566
  • 9
  • 38
  • 68

4 Answers4

11

Methinks that you are looking for templates.

Though you almost nailed it, you are mixing matters a little. Just separate your "design parts" from "code parts". Don't make header to do the job of the actual code and everything become as clear as a fresh water

Let me suggest you the following setup:
A site contains of

  • main config file (suppose it's something like your functions.php)
  • main site template
  • actual pages (or sections) - actual php scripts of different purpose. Each consists of 2 parts:
    • script itself, doing all data mining and preparations, initialising all variables
    • a template, doing the job of data output only.

the main idea is to make PHP script do no output until all data got ready - thus you will get an instant solution of your page title problem. Moreover (think about it):

  • you will be able to send whatever HTTP headers, cookies, start session etc.
  • you will be also able to change whole output appearance on the fly: an XML or JSON instead of HTML for example
  • you will be able to use the same code base for the different sites, changing only templates

Once php script done with data preparations, it calls for the the main site timplate, which, in turn, will include the actual page template.

Thus you will get exactly what you're asking for - the website dynamic enough that it can have easily editable pages, but also be easily editable is a big part of it needs editing - and many more other benefits.

Template I am talking about is a typical PHP script, however, consists mostly of pure HTML, with some PHP code only to display dynamically generated data.

Here you go with some basic yet working example

the page:

<?
//include our settings, connect to database etc.
include dirname($_SERVER['DOCUMENT_ROOT']).'/cfg/settings.php';
//getting required data
$DATA=dbgetarr("SELECT * FROM links");
// setting title for using in the main template
$pagetitle = "Links to friend sites";
//etc
//set page template filename
$tpl = "links.tpl.php";
//and then finally call a template:
include "main.tpl.php";
?>

where main.tpl.php is your main site template, including common parts, like header, footer, menu etc:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My site. <?=$pagetitle?></title>
</head>
<body>
<div id="page">
<? include $tpl ?>
</div>
</body>
</html>

and links.tpl.php is the actual page template:

<h2><?=$pagetitle?></h2>
<ul>
<? foreach($DATA as $row): ?>
<li><a href="<?=$row['link']?>" target="_blank"><?=$row['name']?></a></li>
<? endforeach ?>
<ul>
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
8

I think most experienced coders would tell you to mix your code and your HTML as little as possible. This means doing all of your calculations, then simply passing any variables needed by the view to the view.

They would also tell you to look into the MVC design pattern. In PHP, this is where Controller classes take the initial request, perform the correct operations on the correct business Model classes & then pass needed data to a View class, which would render your HTML.

MVC can go from very simple 3 class variations, to extremely complex "Frameworks" like Zend Framework. If you build your own, look into PHP class autoloading, as it will make your life easier.

Vivek Kodira
  • 2,764
  • 4
  • 31
  • 49
dqhendricks
  • 19,030
  • 11
  • 50
  • 83
  • Take a look at the structure and code of some small and simple PHP frameworks like http://fatfree.sourceforge.net/ – Mathias Bak Nov 23 '11 at 18:50
  • @Mathias Bak I don't know much about it, but the "single file" approach that fat free mentions makes me nervous for performance. they load every ounce of code for every single request? I'd rather use something that loads classes only when those classes are used, but that's just going off their front page, so who knows. – dqhendricks Nov 23 '11 at 19:13
  • maby fat free was a bad example, I don't know how it works, my point was just that looking at a small MVC framework can get one a long way. – Mathias Bak Nov 23 '11 at 20:24
4

The general accepted approach in small sites is to have something like this:

<?php $title = 'Title'; ?>
<?php require_once('header.php'); ?>

Header.php

<title><?php echo $title; ?> - MyWebsite</title>

I think that should work fine for you, while still preserving the K.I.S.S principle.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • Um, I don't think using (what appears to be, in your example) globals is "generally accepted"... please correct me if I'm wrong, or misunderstanding your example... – Aerik Nov 23 '11 at 18:34
  • variables defined in one file and used in another, like here should be avoided, or at least treated VERY carefully. When you come back to your code after 1 year, you don't remember how it works, and it is a pain in the butt if the files depend on eachother like this. So i agree with @Aerik – Mathias Bak Nov 23 '11 at 18:53
  • 2
    @MathiasBak That's what comments are for. When you declare `$title` simply add a comment stating it will be used in `header.php`, also when they are one after another and not 50 lines apart, it's okay. – Madara's Ghost Nov 24 '11 at 13:35
  • @Truth but where should you add the comment. In the header file or in the other file? If you choose the header file, should you update your comment every time you include the file from a new page? What about when you read the page that includes header, and see the variable. It is not used anywhere, or is it? You have to search other files to clean up your code. Takes time = money. – Mathias Bak Nov 24 '11 at 16:56
  • Obviously the comment should go right after you declare the variable, so it is visible to anyone reading. It's also possible to add it in the included file, saying it is "inherited from parent file". I may not have expressed myself correctly, this approach is fine in **small websites**, in more serious large scale websites, you'll need a controller. – Madara's Ghost Nov 24 '11 at 17:04
2

What I have done is make header and footer functions that take an array as a parameter, and the array may contain optional elements, so you would pass in the title, etc. to the header function.

I think one thing you will find that is "generally accepted" is to use PHP more and more as a program, and less to drop out of html when you need dynamic content only. In other words, writing everything as a program that outputs html, not as a mix of html and php (opening and closing the PHP tags).

In this model, many websites only have one "index.php" and that actually generates all the pages (often from a database). But if you've only got handful of pages, then each being it's own php page with shared header and footer functions is a fine way to go, IMHO.

Aerik
  • 2,307
  • 1
  • 27
  • 39
  • I like the idea of simply having some functions to do, and I overlooked the idea of sending it parameters. So, you're also saying to use `echo 'html...';`, rather than `?>html... – Joseph Duffy Nov 23 '11 at 18:22
  • Yes, that's exactly what I'm saying. the code looks a little cleaner when it's all code, and when you have your html inside of variables or functions, it gives you more control about sending it to the client. It's also a step toward enabling internationalization, but that may not be a factor for you. – Aerik Nov 23 '11 at 18:31