[PHP for Beginners] Switch Pages Freely! Let's Understand the Mechanism by Creating a Simple Router
Through our learning so far, we've become able to retrieve information from a database and generate dynamic pages using PHP. However, it's normal for a website to have multiple different pages, such as a "Top Page," "About Us," and "Contact." How can we efficiently manage these pages while sharing common elements like headers and footers?
The answer lies in a concept called "routing." Routing is a mechanism that acts as "traffic control," switching the content to be displayed according to the URL the user has accessed. In this article, we will create a very simple router in PHP using URL parameters like `index.php?page=about`. By touching on the core part of what full-fledged frameworks like Laravel are doing behind the scenes, let's deepen our understanding of web application structure and take a big step toward our next learning goal!
To get your PHP running (development environment), if you haven't set up XAMPP yet, please refer to [PHP for Beginners] A Complete Guide to Downloading and Installing XAMPP!. After installation, place your PHP file in the specified folder (like `htdocs`), and you're all set!
1. What is the Mechanism of Routing? Traffic Control by PHP
The mechanism of routing can be compared to an information desk clerk in a large building. All visitors (users) first arrive at the same main entrance (index.php). Then, they tell the clerk (router), "I want to go to the XX department (?page=about)." The clerk then guides them to the appropriate department (about.php) according to their destination.
To create this mechanism, we will use the following three elements of PHP.
$_GETvariable: A special PHP variable for receiving the value of `page` (in this case, `about`) from a "query string" like?page=aboutappended to the end of the URL.includestatement: A command to read and combine the contents of another PHP file at a specified location. This allows you to share common elements like headers and footers.file_exists()function: A very important security function that checks whether the file you are trying to load actually exists on the server, in case a malicious URL is specified.
By combining these parts, a router that switches the display content according to the URL is completed.
2. In Practice! Let's Create a Simple Router with 3 Files
Now, let's actually create a simple router. This time, we will prepare the following three files and save them all in the same folder.
- index.php: The layout that serves as the skeleton for all pages and the router itself that handles traffic control.
- home.php: The content part to be displayed as the top page.
- about.php: The content part to be displayed as the "About this site" page.
File 1: index.php (Router & Layout)
This file is the "main entrance" of our site. It has common parts like navigation and a content display area that switches according to the URL. This will be our "fully working complete HTML example."
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Router Site</title>
<style>
body { font-family: sans-serif; line-height: 1.8; }
.container { max-width: 800px; margin: 20px auto; padding: 20px; border: 1px solid #ddd; }
nav { background: #f0f0f0; padding: 10px; margin-bottom: 20px; }
nav a { margin-right: 15px; text-decoration: none; color: #0056b3; }
nav a:hover { text-decoration: underline; }
.content { border-top: 2px solid #eee; padding-top: 20px; }
footer { margin-top: 30px; text-align: center; font-size: 0.9em; color: #777; }
.not-found { color: red; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<header>
<h1>Simple Router Sample Site</h1>
</header>
<nav>
<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About This Site</a>
</nav>
<div class="content">
<?php
// 1. Get the page name to display from the URL parameter
// If no parameter, 'home' is the default
$page = $_GET['page'] ?? 'home';
// 2. List of allowed pages (whitelist)
$allowed_pages = ['home', 'about'];
// 3. Check if the page name is in the allowed list
if (in_array($page, $allowed_pages)) {
// 4. Create the corresponding file path
$file_path = $page . '.php';
// 5. Final check if the file exists before including it
if (file_exists($file_path)) {
include($file_path);
} else {
echo '<p class="not-found">Error: File not found.</p>';
}
} else {
// If a non-allowed page is specified
echo '<p class="not-found">404 Not Found: The specified page does not exist.</p>';
}
?>
</div>
<footer>
<p>© 2025 Simple Router Inc.</p>
</footer>
</div>
</body>
</html>
File 2: home.php (Home Content)
This is a file that only contains the content for the home (top) page, which will be included in `index.php`.
<h2>Welcome!</h2>
<p>This is the homepage.</p>
<p>When you click the navigation above, the value of ?page= in the URL changes, and the displayed content switches.</p>
File 3: about.php (About Site Content)
Similarly, this is the content that is loaded when `index.php?page=about` is specified.
<h2>About This Site</h2>
<p>This site is a sample for learning the mechanism of a simple PHP router.</p>
<p>index.php serves as the base, and it dynamically loads the content of different files like this about.php according to the URL parameter.</p>
Now you're all set. Try accessing `index.php` in your browser. You should be able to confirm that each time you click a navigation link, only the central content switches between "Home" and "About This Site."
3. A Point to Be Careful About: Directory Traversal Attack
When creating a simple router yourself, one thing you absolutely must know about is the **Directory Traversal** attack. If you write code like the following without security measures, it is very dangerous.
<?php
// Bad example: Do not ever imitate this!
$page = $_GET['page'];
include($page . '.php'); // Using user input as is without validation
?>
With this code, an attacker could specify a special string in the URL like `?page=../../../../etc/passwd`, potentially allowing them to read important server configuration files that should not be accessed.
To prevent this attack, our `index.php` example includes a two-step check.
- Whitelist Method: Create a permission list called `$allowed_pages` and check if the specified page name is in it using `in_array()`.
- File Existence Check: Even if it passes the permission list, as a precaution, perform a final check to see if the file actually exists with `file_exists()`.
This countermeasure prevents unintended files from being loaded and enhances security.
4. Summary and Next Steps
This time, we learned the mechanism of a simple router that switches the displayed content using URL parameters and PHP's `include` statement. Did you get a feel for how a whole website can be constructed with a single entry point, `index.php`, handling the traffic control according to the URL?
In fact, the modern PHP frameworks we commonly use, like Laravel and Symfony, provide a more advanced and secure version of this routing mechanism. The knowledge from this article is an important foundation for understanding why such frameworks are necessary and what is happening behind the scenes.
As a next step, it would be interesting to try creating "**pretty URLs**" by rewriting URLs using an `.htaccess` file, to make URLs like `index.php?page=about` look more beautiful, like `/about`. This would surely deepen your understanding of how the web works.