Lesson 10 - Putting web pages together using PHP
In the previous lesson, Improving the e-mail form in PHP, we finished our e-mail form in PHP. We're able to handle forms pretty well now. In today's tutorial, we're going to look at putting pages together dynamically.
Putting pages together
Most websites nowadays are made up of 2 parts. The first part is the layout, which is seen in each individual subpage. A layout commonly includes the website's logo, a navigation bar, and a footer. The second part is the current article, which is displayed in the layout.
Back when static web pages were the only option, people had to copy the layout to each and every subpage manually. During the same time period, frames were used to embed content, but they have since then been removed from HTML due to a lot of issues. It would be very hard to handle our code if we did things like they did. Mainly because if we wanted to change something in our layout, we would have to go back and do it in every subpage as well.
Thanks to what you know in PHP, you can now insert the article into the
layout automatically. All we would then need is files containing subpages
(without a layout) on our website because the layout would be part of the
index.php
file. We would then insert the subpage requested by the
user into the layout. The user will request the article (subpage) using the
GET
method, meaning that he/she will enter the article name into
the URL address.
Here's sort of what it will look like:
The different ways of assembling websites
There are generally two ways of assembling dynamic websites. One way we've already mentioned (adding a subpage into the layout), or we could insert the layout into subpages as a header before the subpage and a footer after the subpage. We're going to go with the first one since this is the approach we will later use to load articles from a database.
Preparing files
Let's create a new project and prepare the necessary files. We're going to
need an index.php
that will contain our layout. I've borrowed the
following layout from our HTML course, you can
go ahead and use it as well (make sure you download the required styles and
images). If you want, you could make a custom layout, anything that at least has
a title will do
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="style.css" type="text/css" /> <title>HoBi's portfolio</title> </head> <body> <header> <div id="logo"><h1>HoBi</h1></div> <nav> <ul> <li><a href="index.php?page=home">Home</a></li> <li><a href="index.php?page=about-me">About me</a></li> <li><a href="index.php?page=skills">Skills</a></li> <li><a href="index.php?page=references">References</a></li> <li><a href="index.php?page=contact">Contact</a></li> </ul> </nav> </header> <article> <div id="centerer"> <header> <h1>About me</h1> </header> <section> <?php ?> </section> <div class="clearer"></div> </div> </article> <footer> Made by ©HoBi for <a href="http://ict.social">ICT.social</a> </footer> </body> </html>
Our layout contains an HTML head, which is the website's header and includes a logo and a navigation bar. Notice that the URLs link to:
index.php?page=home
All of those URLs point to the layout file and pass the subpage's name. We
will use this to our advantage, and insert the currently selected page into its
parameters. We'll add the HTML sub pages into a new folder, name it
subpages/
, and add the .php
extension to each of the
files.. For example, the "about-me" subpage will be saved as:
subpages/about-me.php
Subpages could theoretically have an .html extension, but we will need to add PHP script into some of them, e.g. our contact form.
Notice the empty PHP sequence in the <section>
element.
That's where we'll insert the requested subpage.
Create the subpages/
folder and a few subpages in there with the
.php
extension.
Inserting files
In PHP, there are generally two ways to insert file contents into a script.
Inserting text
If we wanted to insert the file contents as text, we would use the
file_get_contents()
PHP function. The function takes the path to
the file as a parameter and returns the file contents as a string.
We could insert the contents of our subpage using the following code. The code shown here is not safe yet, we'll solve all of its security vulnerabilities at the end of this lesson.
// this script is not safe $content = file_get_contents('subpages/' . $_GET['page'] . '.html'); echo $content;
As you can see, I concatenated the .html
extension to the path
string. If we had a PHP script in a subpage and inserted it into the layout
using the file_get_contents() function, the script's code would be printed
instead of being executed. That could prove to be quite dangerous since PHP
scripts usually contain database login credentials and other sensitive data.
However, when we need to insert HTML or regular text from a file, this function
will get the job done right.
Another security issue is that the user could write whatever he/she wants into the URL parameter. Meaning that he/she could print file contents that we didn't mean to expose.
Inserting a script
If we want the file contents to be executed as PHP script, we would have to
use the require()
function. This function takes a file path as a
parameter and prints the file contents immediately. If the file contains PHP
sequences, they will be executed.
Let's insert the following code into the PHP sequence in
index.php
:
// this script is not safe require('subpages/' . $_GET['page'] . '.php');
Let's go ahead and try to enter a subpage address:
Try the navigation bar out, each subpage will be inserted into the layout and the entire page will be displayed in your web browser. We've just made our work much easier and made room for future improvements when we get to loading text from a database.
Note: Other than require()
, we could also use the
include()
function. It does the same thing with only one slight
difference. If PHP fails to process the file, a warning message will be printed
out instead of it terminating the entire application.
Security
BEWARE! Both functions mentioned above can be very dangerous. You can create a nasty security backdoor if you don't use them properly.
The problem is that we're displaying the content of a file whose name is
entered by the user. The user can request e.g. the .htpasswd
file
containing passwords like this:
http://yourwebsite.com/index.php?page=../.htpasswd
The ../
sequence would move him/her up a folder in the
directory. This would then give him/her access to our website's root folder.
Then the attacker would be able to access and display absolutely everything.
Handling security issues
To fix this security leak, we'll have to sanitize the user's input so that it
only contains alphabetical and numerical characters. We can do that with the
help of a regular expression. The theory behind these expressions is rather
complicated. Simply put, it is a "mini-language" (the correct term is
metalanguage) that is used mainly for checking string contents. We'll talk about
them in further detail in another course. For now, all you need to know is that
they are used when checking a string's content. We will use PHP's
preg_match()
function, which returns 1
if the text
matches a given pattern.
We'll also change require()
to include()
and
display an error message in case the text processing wasn't successful. We can't
ask if the process was successful with require()
because the
application terminates when an error occurs. If there is no URL parameter, we'll
display the home page.
if (isset($_GET['page'])) $page = $_GET['page']; else $page = 'home'; if (preg_match('/^[a-z0-9\-]+$/', $page)) { $inserted = include('subpages/' . $page . '.php'); if (!$inserted) echo('Requested page was not found.'); } else echo('Invalid parameter.');
Your website is now secure and you will no longer have to copy the layout manually. You could also add the subpage containing our contact form if you'd like.
Web application security should always be kept in mind whenever you add something that a user may be able to use to enter text. You must always ask yourself could this value lead to a security leak?
The completed website can be downloaded below the article. In the next lesson, For and while loops in PHP, we'll talk about loops (we're getting closer to working with databases).
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 273x (1.09 MB)
Application includes source codes in language PHP