I have a lot of experience coding static HTML and CSS (and enough Javascript to scrape through in a pinch) but I am trying to make the leap to coding dynamically-generated web pages using PHP.
To this end, I’ve read “Kevin Yank’s Build Your Own DB-Driven Website”, and I can follow the train of logic when I see the code and make things work according to the instructions in the book, but when it comes to actually writing code on my own, I have trouble.
So… I thought I would try a really simple exercise: a dummy website that uses one PHP controller (index.php) to pull up different articles depending on what the user clicks. I have posted this site at:
I guess I got it to work, for the most part, but I can’t help but feel that there is a more eloquent way to code what I am doing. Specifically, there are 3 issues I am wondering about:
Is there a way to include the footer only once rather than over and over again? If I place it below all the “if” statements, it gets “eaten up” by the exit() function.
If the user types in a page that doesn’t exist, I would like for them to be redirected to a custom 404 “page not found” error message. As things stand, they just get redirected to the home page.
Lastly, just wondering… is the phenomenon of the “?+linkname” appearing in the URL unavoidable? Is it OK? Is it bad? What are the current conventions?
Or perhaps there is a sleeker, sexier, more svelte way to structure the whole site, and I’m missing the boat?
I have made available for download a zip file containing all the pages used to build the site (not many) at:
If you’d rather just see the code, I am copying and pasting the gist of the index.php page below.
Any advice would be greatly appreciated.
<body>
<div id="wrapper">
<?php
include 'header.inc.html.php';
include 'nav.inc.html.php';
if (isset($_GET['home']))
{
include 'home.html.php';
include 'footer.inc.html.php';
exit();
}
if (isset($_GET['about']))
{
include 'about.html.php';
include 'footer.inc.html.php';
exit();
}
if (isset($_GET['contact']))
{
include 'contact.html.php';
include 'footer.inc.html.php';
exit();
}
include 'home.html.php';
include 'footer.inc.html.php';
?>
</div><!--wrapper-->
</body>
Thanks. I was unable to implement the switch statement (I know how to do them in C++, but I’m unfamiliar with the syntax in PHP – particularly when it comes to specifying the links and all that.) I did, however, while looking up the switch, run across the “elseif” format, and I was able to make that work.
I think it’s an improvement, because the “footer” include only gets stated once now, instead of repeatedly, and we avoid all of the exit() functions. But if an invalid URL is typed in, it still takes the user back to the home page instead of the 404 error page as I would like. I guess for that to happen, the “error” include should appear in the “else” clause, but if I do that, then the error page would come up when you’d type in the directory’s URL (i.e. http://www.trilefile.com/fortunecookie/)
So I guess it boils down to: is there a way to specify an if-clause that would direct the user to the home page if no particular URL directory is specified? – meaning, if the user just types in http://www.trilefile.com/fortunecookie/
The improved code:
<body>
<div id="wrapper">
<?php
include 'header.inc.html.php';
include 'nav.inc.html.php';
if (isset($_GET['home']))
{
include 'home.html.php';
}
elseif (isset($_GET['about']))
{
include 'about.html.php';
}
elseif (isset($_GET['contact']))
{
include 'contact.html.php';
}
else
{
include 'home.html.php';
/*I would like for this to be include 'error.html.php';
but as things stand, that would make the URL
http://www.trilefile.com/fortunecookie/ lead to
the error page instead of the home page*/
}
include 'footer.inc.html.php';
?>
</div><!--wrapper-->
</body>
Yes, that works. (The only thing was that when I tested the code, somehow I wound up with double the amount of div’s because they were both in the includes and in the index file, so I edited them out, but that’s peripheral.)
So the fully functional code is below. Thanks ever so much.
Just out of curiosity, I understand the switch statement, and the setting of default to “home”, but what’s all that stuff in the beginning? Lines 2 & 3, I assume, are a built-in error reporting function, but what are array_keys and how does that $mode variable get set up?
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'on');
$mode = 'home'; // default
if (! empty($_GET))
{
$mode = array_keys($_GET);
$mode = $mode[0];
}
switch($mode)
{
case 'home' : $blurb = 'home.html.php';
break;
case 'about' : $blurb = 'about.html.php';
break;
case 'contact' : $blurb = 'contact.html.php';
break;
default : $blurb = 'error.html.php';
}//endswitch
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Fortune Cookie Fan Club</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="style1.css" />
</head>
<body>
<div id="wrapper">
<?php include 'header.inc.html.php'; ?>
<?php include 'nav.inc.html.php'; ?>
<?php include $blurb; ?>
<?php include 'footer.inc.html.php'; ?>
</div><!--wrapper-->
</body>
</html>
Did you scroll to the bottom and see the source code?
Your DIVs were duplicated in your include files so I removed then and placed a single reference in the index.php file. It will be a lot easier in the future to make a single change that affects the whole site.
The $mode is tested to see if the URI parameter $_GET array() is passed else use the default value. If it is set the $mode is extracted. Download the following PHP document help file and lookup the functions that I use to parse the $mode variable. Lookup “Array functions”.
//==============================================
//
// usage:
// show_array($array_value);
//
// Result:
// displays formatted contents of $array_value
//
//==============================================
function show_array($value = array('Red','Yellow','Blue', 'Green'))
{
if (is_array($value))
{
echo '<pre>';
print_r($value);
echo '</pre>';
}else{
echo 'The vaule you passed is not an array';
}//endif
}//endfunc
I programmed in C and C++ a long time ago and found it is very similar syntax to PHP. Beware of the PHP non-stict types. No doubt you will be caught out and the PHP documentation is essential.
using that new php code, i was able to implement contextual navigation with a $bodyid variable. So that a little border lights up around whatever page you’re on at the moment.
You just have to stick the following stuff in your stylesheet…
I did scroll down to the bottom, but only saw the source code for the index, not the includes, which is why I was confused about the DIVs at first. But I get it now. And I checked the 404 File not found page; it works fine.
Many thanks for all your help and explanations, and I’ll be sure to check out the documentation.
This is a very clever solution: I tried it out in my code. But, since I’m just starting out, the switch statement is I perhaps easier to wrap my mind around. Also, it allowed me to easily implement contextual navigation, which works really nicely.
The negative side of your solution is, that you’ll have to change the switch statement each time you want to add a page to your website. While pmw57’s solution is flexible.
In every one of those route arrays you can now define data that changes but is present on every page such as; the title,body id, etc etc w/o it being bound to the mode name. You can also build your navigation dynamically using the route configuration. Meaning if you ever need to add a page you won’t have to touch the template code just the route configuration.
I don’t recommend people use this method. Unless some robust validation is performed on the value of the $mode variable, it’s a security issue. null bytes are the problem here. It lets an attacker make php ignore the ‘.html.php’ suffix, and with that, they can pretty much provide the name and path to any file on the system.
Sorry to keep bugging you, but I was wondering: how is it an advantage to place the DIVs in the index.php file rather than the includes? Don’t get me wrong: I believe you wholeheartedly, and I definitely want to make things easier in the future, but I just can’t follow through the thinking process that far ahead.
I just must be missing my ticket for the logic train on this one.
I think that it is easier to read and understand the script flow. Also debugging is easier because each include can be remmed and you will still have the basice outline.
Try remming each include statement and use the debug style div {outline: dotted 1px #f00}.
Also the CSS article unique headers are duplicated which I find confusing.
The code you supplied is difficult to understand and especially once you return to debug after about a month.