🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【PHP入门】自由切换页面!制作一个简单的路由器来理解其机制

通过至今的学习,我们已经能够使用PHP从数据库获取信息并生成动态页面了。但是,一个网站通常会有“首页”、“公司简介”、“联系我们”等多个不同的页面。我们该如何有效地管理这些页面,同时共用页眉和页脚呢?

答案就在于“路由(Routing)”这一概念。路由是一种扮演“交通指挥”角色的机制,它根据用户访问的URL来切换要显示的内容。在本文中,我们将使用像`index.php?page=about`这样的URL参数,用PHP亲手制作一个非常简单的路由器。通过接触Laravel等功能强大的框架背后所做的工作的核心部分,来加深对Web应用程序结构的理解,并为下一步的学习迈出重要的一步吧!

要准备运行PHP(开发环境),如果还没有搭建XAMPP的朋友,请参考【PHP入门】XAMPP下载及安装方法完全解析!。 安装后,将PHP文件放置在指定文件夹(如 `htdocs`)中,准备工作就完成了!

1. 什么是路由机制?PHP实现的交通指挥

路由的机制可以比作一座大楼的前台接待员。所有的访客(用户)首先都会来到同一个正门(index.php)。然后,他们告诉前台(路由器)“我想去XX部门(?page=about)”。接着,前台就会根据他们的目的地,引导他们去往相应的部门(about.php)。

为了创建这个机制,我们会使用PHP的以下三个元素。

  1. $_GET变量: 一个PHP的特殊变量,用于从URL末尾附加的像?page=about这样的“查询字符串”中,获取page的值(在此例中是`about`)。
  2. include语句: 一个命令,用于读取另一个PHP文件的内容,并将其合并到指定位置。这样可以实现页眉和页脚的共用。
  3. file_exists()函数: 一个在安全上非常重要的函数,用于检查我们试图加载的文件是否实际存在于服务器上,以防备指定了恶意的URL。

通过组合这些部件,一个能根据URL切换显示内容的路由器就完成了。

2. 实践!用3个文件制作一个简单的路由器

那么,让我们实际来制作一个简单的路由器吧。这次我们将准备以下三个文件,并全部保存在同一个文件夹中。

文件1: index.php (路由器兼布局)

这个文件是我们网站的“正门”。它拥有导航等公共部分,以及一个根据URL切换内容的显示区域。这将成为我们“可以完整运行的HTML示例”。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>简单路由器网站</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>简单路由器示例网站</h1>
        </header>
        <nav>
            <a href="index.php?page=home">首页</a>
            <a href="index.php?page=about">关于本站</a>
        </nav>

        <div class="content">
            <?php
            // 1. 从URL参数中获取要显示的页面名称
            //    如果没有参数,则默认为 'home'
            $page = $_GET['page'] ?? 'home';

            // 2. 允许显示的页面列表(白名单)
            $allowed_pages = ['home', 'about'];

            // 3. 检查页面名称是否在允许列表中
            if (in_array($page, $allowed_pages)) {
                // 4. 创建对应的文件路径
                $file_path = $page . '.php';

                // 5. 最后确认文件是否存在后再加载
                if (file_exists($file_path)) {
                    include($file_path);
                } else {
                    echo '<p class="not-found">错误:找不到文件。</p>';
                }
            } else {
                // 如果指定了不允许的页面
                echo '<p class="not-found">404 Not Found: 指定的页面不存在。</p>';
            }
            ?>
        </div>

        <footer>
            <p>© 2025 Simple Router Inc.</p>
        </footer>
    </div>
</body>
</html>

文件2: home.php (首页内容)

这是一个只包含首页(顶级页面)内容的文件,它将被加载到`index.php`中。

<h2>欢迎!</h2>
<p>这里是首页。</p>
<p>点击上方的导航,URL中 ?page= 的值会发生变化,显示的内容也会随之切换。</p>

文件3: about.php (关于本站的内容)

同样,这是当指定`index.php?page=about`时加载的内容。

<h2>关于本站</h2>
<p>本站是用于学习PHP简单路由机制的示例。</p>
<p>index.php作为基础,根据URL参数动态地加载about.php等不同文件的内容。</p>

这样就准备好了。请在浏览器中访问`index.php`试试看。您应该能确认到,每当点击导航链接时,只有中央的内容部分在“首页”和“关于本站”之间切换。

3. 注意事项:目录遍历攻击

在亲手制作简单路由器时,绝对必须了解的一种攻击是**目录遍历(Directory Traversal)**攻击。如果未采取安全措施就编写如下代码,会非常危险。

<?php
// 坏例子:绝对不要模仿!
$page = $_GET['page'];
include($page . '.php'); // 未经验证就直接使用用户输入
?>

使用这段代码,攻击者可以在URL中指定像`?page=../../../../etc/passwd`这样的特殊字符串,从而有可能读取到服务器上本不应被访问的重要配置文件等。

为了防止这种攻击,我们的`index.php`示例中加入了两个阶段的检查。

  1. 白名单方式: 创建一个名为`$allowed_pages`的允许列表,并用`in_array()`检查指定的页面名称是否在其中。
  2. 文件存在性确认: 即使通过了允许列表的检查,为保险起见,最后再用`file_exists()`确认文件是否实际存在。

通过这项对策,可以防止加载意料之外的文件,从而提高安全性。

4. 总结与后续步骤

这次,我们学习了使用URL参数和PHP的`include`语句来切换显示内容的简单路由机制。您是否体会到,通过一个入口`index.php`根据URL进行交通指挥,从而构建整个网站的感觉了呢?

实际上,我们平时使用的Laravel、Symfony等现代PHP框架,提供了比这更高级、更安全的路由机制。本次的知识,是理解这些框架为何必要、以及其背后工作原理的重要基础。

作为下一步,尝试使用`.htaccess`文件来重写URL,将`index.php?page=about`这样的URL变得更美观,如`/about`,挑战一下“**友好URL(Pretty URL)**”也是很有趣的。这必将使您对Web机制的理解更加深刻。