PHP 如何做路由
在搭建个人网站或小型项目时,很多新手开发者会遇到一个小麻烦:明明在浏览器输入了 /blog/2024/05,却访问不到对应的文章页面,反而跳转到了 PHP 脚本的主页面。这其实就是路由没做好导致的问题——简单来说,路由就是帮网站把不同的 URL 地址,对应到不同的页面或功能代码的“导航员”。
很多人可能会觉得“路由是框架才有的东西”,但其实用原生 PHP 也能实现,不用额外依赖复杂工具,咱们用生活化的例子就能讲明白。

先搞懂基础逻辑:路由像小区的门牌号
把网站比作一个小区,每个功能区域就是一栋楼,路由就是小区门口的门牌号指引:输入 /home 就去住宅楼,输入 /shop 就去商铺,输入 /article/123 就去找编号123的单元楼。
在 PHP 里,这个指引过程只需要两步:先把用户输入的 URL“拆成小片段”,再根据片段内容执行对应的代码。比如用户输入 http://你的网站地址/blog/2024/05,咱们把它拆成 ['blog', '2024', '05'],然后让 PHP 只加载处理博客列表的代码,而不是首页的代码。
原生 PHP 实现简单路由:从拆分到匹配
不用框架的话,实现路由其实只需要几行代码。咱们拿最常用的 Apache 服务器举例子,它有个叫 .htaccess 的文件,作用是“改写 URL”——把类似 index.php?page=blog 的长地址,变成干净的 /blog,让用户看着舒服,也符合搜索引擎的抓取规则,这对 SEO 很重要。
先写 .htaccess 文件的核心内容,放在网站根目录就行:
`apache
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L]
`
这段代码的意思是:如果用户访问的文件或文件夹不存在,就把所有请求都转发给 index.php,这样所有 URL 都会经过咱们的 PHP 处理。
接下来就是 index.php 里的路由逻辑,咱们用数组把不同的路径对应到功能:
`php
// 把当前请求的 URL 片段拆出来,比如 /blog/2024 就变成 ['blog', '2024']
$path = isset($_SERVER['PATH_INFO']) ? trim($_SERVER['PATH_INFO'], '/') : '';
$segments = $path ? explode('/', $path) : [];
// 简单的路由匹配
if (empty($segments)) {
// 输入根地址,显示首页
include 'pages/home.php';
} elseif ($segments[0] == 'blog') {
if (isset($segments[1]) && is_numeric($segments[1])) {
// 输入 /blog/123,显示编号123的博客详情
include 'pages/blog_detail.php';
} else {
// 输入 /blog,显示博客列表
include 'pages/blog_list.php';
}
} else {
// 没匹配到,显示404页面
include 'pages/404.php';
}
`
这个逻辑就像给不同的门牌号安排不同的楼,新手也能看懂,还能根据自己的需求加新的路径,比如输入 /about 就显示关于我们的页面。
进阶一点:用正则处理复杂路径
如果路径格式不固定,比如要匹配 /article/2024/05/10 这种带日期的 URL,用“固定片段判断”就会很麻烦,这时候可以用正则表达式,相当于给门牌号加更灵活的匹配规则。
比如要匹配所有 /article/年份/月份/日期 的格式,正则可以写成 ^/article/(\d{4})/(\d{2})/(\d{2})$,在 PHP 里用 preg_match 函数就能提取出对应的年、月、日,然后加载对应的文章代码。这种方法适合需要动态匹配的场景,比如电商网站的商品详情页。
避坑提醒:原生路由别乱加功能
很多新手会忍不住在原生路由里加数据库查询、页面渲染这些复杂逻辑,结果代码乱成一团,维护起来特别麻烦。其实原生路由的核心作用只是“分发请求”,具体的页面逻辑,比如展示文章、处理表单,应该单独放在对应的文件里,就像咱们刚才的例子,把首页、博客列表的代码分开存,改起来也方便。
如果网站规模变大,比如需要做用户登录、商品分类这些功能,再用框架的路由会更高效——框架已经帮你把路由的复杂逻辑写好了,不用自己从零搭建,还能自动满足 SEO 的 URL 规范,让你的网站更容易被搜索引擎抓取。