本文目录导读:

我来为你详细介绍PHP实现伪静态路由的几种方法:
基础原理
伪静态是将动态URL转换为静态形式的URL,主要通过Web服务器配置和PHP路由实现。
Web服务器配置
Apache (.htaccess)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# 排除真实存在的文件
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 将所有请求重定向到index.php
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Nginx
server {
listen 80;
server_name example.com;
root /var/www/html;
# 排除存在的文件
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
PHP路由实现
简单路由类
<?php
class Router {
private $routes = [];
private $params = [];
// 注册路由规则
public function add($method, $pattern, $handler) {
$this->routes[] = [
'method' => $method,
'pattern' => $pattern,
'handler' => $handler
];
return $this;
}
// 处理GET请求
public function get($pattern, $handler) {
return $this->add('GET', $pattern, $handler);
}
// 处理POST请求
public function post($pattern, $handler) {
return $this->add('POST', $pattern, $handler);
}
// 匹配并执行路由
public function dispatch() {
$uri = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
// 去除查询字符串和开头的/
$uri = parse_url($uri, PHP_URL_PATH);
$uri = ltrim($uri, '/');
foreach ($this->routes as $route) {
if ($route['method'] === $method) {
$pattern = $this->convertToRegex($route['pattern']);
if (preg_match($pattern, $uri, $matches)) {
array_shift($matches);
$this->params = $matches;
// 调用控制器方法
list($controller, $action) = explode('@', $route['handler']);
$this->callAction($controller, $action, $matches);
return;
}
}
}
// 404处理
$this->notFound();
}
// 转换路由规则为正则
private function convertToRegex($pattern) {
// 将 {id} 转换为正则表达式
$pattern = preg_replace('/\{(\w+)\}/', '(?P<$1>[^/]+)', $pattern);
return "/^" . str_replace('/', '\/', $pattern) . "$/";
}
// 调用控制器方法
private function callAction($controller, $action, $params) {
$controllerClass = ucfirst($controller) . 'Controller';
if (class_exists($controllerClass)) {
$instance = new $controllerClass();
if (method_exists($instance, $action)) {
call_user_func_array([$instance, $action], $params);
return;
}
}
$this->notFound();
}
// 404页面
private function notFound() {
http_response_code(404);
echo "404 Not Found";
}
}
使用示例
<?php
// index.php
require_once 'Router.php';
$router = new Router();
// 定义路由规则 (伪静态)
$router->get('/', 'home@index');
$router->get('articles/{id}', 'article@show');
$router->get('category/{name}/{page}', 'category@show');
$router->post('user/login', 'user@login');
// 模拟控制器
class HomeController {
public function index() {
echo "首页";
}
}
class ArticleController {
public function show($id) {
echo "显示文章ID: " . $id;
}
}
class CategoryController {
public function show($name, $page = 1) {
echo "分类: $name, 页码: $page";
}
}
class UserController {
public function login() {
echo "处理登录";
}
}
// 执行路由
$router->dispatch();
高级路由实现(带参数类型约束)
<?php
class AdvancedRouter {
private $routes = [];
private $middleware = [];
// 添加带约束的路由规则
public function add($method, $pattern, $handler, $constraints = []) {
$this->routes[] = [
'method' => $method,
'pattern' => $pattern,
'handler' => $handler,
'constraints' => $constraints
];
return $this;
}
// 解析路由参数
private function parseParams($pattern, $uri) {
$params = [];
$patternSegments = explode('/', trim($pattern, '/'));
$uriSegments = explode('/', trim($uri, '/'));
foreach ($patternSegments as $key => $segment) {
if (isset($uriSegments[$key])) {
if (strpos($segment, '{') === 0) {
// 提取参数名
preg_match('/\{(\w+)\}/', $segment, $matches);
$paramName = $matches[1];
$params[$paramName] = urldecode($uriSegments[$key]);
} elseif ($segment !== $uriSegments[$key]) {
return false;
}
} else {
return false;
}
}
return $params;
}
// 生成URL(反解析)
public function url($name, $params = []) {
foreach ($this->routes as $route) {
if ($route['hasName'] ?? false && $route['name'] === $name) {
$url = $route['pattern'];
foreach ($params as $key => $value) {
$url = str_replace("{$key}", $value, $url);
}
return '/' . $url;
}
}
return '#';
}
// 分组路由
public function group($prefix, $callback) {
// 保存当前分组前缀
$oldPrefix = $this->groupPrefix ?? '';
$this->groupPrefix = $oldPrefix . '/' . trim($prefix, '/');
call_user_func($callback, $this);
// 恢复旧前缀
$this->groupPrefix = $oldPrefix;
}
}
完整示例项目结构
project/
│
├── .htaccess
├── index.php
├── router/
│ └── Router.php
├── controllers/
│ ├── HomeController.php
│ ├── ArticleController.php
│ └── UserController.php
└── views/
├── home.php
└── article.php
缓存和性能优化
<?php
class CachedRouter {
private $cacheFile = 'route_cache.php';
private $routes;
public function __construct() {
// 检查是否有缓存的路由
if (file_exists($this->cacheFile)) {
$this->routes = require $this->cacheFile;
} else {
$this->routes = [];
}
}
public function add($pattern, $handler) {
$this->routes[$pattern] = $handler;
// 保存到缓存文件
$this->saveToCache();
return $this;
}
private function saveToCache() {
$data = "<?php return " . var_export($this->routes, true) . ";";
file_put_contents($this->cacheFile, $data);
}
public function dispatch() {
$uri = $_SERVER['REQUEST_URI'];
// 直接从数组查找
if (isset($this->routes[$uri])) {
return $this->callAction($this->routes[$uri]);
}
// 动态匹配
foreach ($this->routes as $pattern => $handler) {
if ($this->matchPattern($pattern, $uri)) {
return $this->callAction($handler);
}
}
$this->notFound();
}
}
使用Composer包
也可以使用PHP生态中成熟的路由库:
# 安装Slim框架 composer require slim/slim # 或使用FastRoute composer require nikic/fast-route
<?php
// 使用FastRoute示例
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/articles/{id:\d+}', 'article/show');
$r->addRoute('GET', '/category/{name}', 'category/show');
});
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
// 404
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
// 405
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
// 执行路由
break;
}
SEO友好的URL生成
<?php
function friendlyUrl($title) {
// 转换为小写
$slug = strtolower($title);
// 替换特殊字符
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
// 去除多余的连字符
$slug = trim($slug, '-');
return $slug;
}
// URL生成
$url = '/articles/' . friendlyUrl("PHP路由实现伪静态") . '-' . $articleId;
注意事项
- 安全性:路由参数需要适当过滤,防止SQL注入和XSS攻击
- 性能:合理使用路由缓存,避免正则表达式过度复杂
- 兼容性:确保服务器支持URL重写功能
- 维护性:保持路由规则清晰,定期清理无效路由
这就是PHP实现伪静态路由的主要方法,根据项目规模和需求,可以选择简单实现或使用成熟的框架。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播