PHP单文件路由类
路由类
Router.php
<?php
class Router
{
private $routes = [];
private $routeCount = 0;
public function addRoute($method, $url, $callback)
{
$this->routes[] = ['method' => $method, 'url' => $url, 'callback' => $callback];
$this->routeCount++;
}
public function doRouting()
{
$is_match=0;
// I used PATH_INFO instead of REQUEST_URI, because the
// application may not be in the root direcory
// and we dont want stuff like ?var=value
$reqUrl = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);//$_SERVER['PATH_INFO'];
if ($reqUrl == null) {
$reqUrl = '';
}
$reqMet = $_SERVER['REQUEST_METHOD'];
foreach ($this->routes as $route) {
// convert urls like '/users/:uid/posts/:pid' to regular expression
$patterns = array('/\[[a-zA-Z0-9\_\-\/]+\]/','/\[{[a-zA-Z0-9\_\-}]+\]/','/\[\/{[a-zA-Z0-9\_\-}]+\]/','/{[a-zA-Z0-9\_\-}]+/');
$replace = array('([a-zA-Z0-9\-\_\/]*)','([a-zA-Z0-9\-\_]*)','([a-zA-Z0-9\-\_\/]*)','([a-zA-Z0-9\-\_]+)');
// $pattern = "@^" . preg_replace('/\\\:[a-zA-Z0-9\_\-]+/', '([a-zA-Z0-9\-\_]+)', preg_quote($route['url'])) . "$@D";
$pattern = "@^" . preg_replace($patterns, $replace, $route['url']) . "$@D";
$matches = array();
// check if the current request matches the expression
if (preg_match($pattern, $reqUrl, $matches)) {
// remove the first match
array_shift($matches);
foreach ($matches as $key => $value) {
if (empty($value)) {
unset($matches[$key]);
}
}
// call the callback with the matched positions as params
if ($route['method'] !=='*' && $reqMet !=='HEAD' && (
!empty($route['method']) &&
!in_array($reqMet, explode(',', $route['method'])))
) {
throw new Exception("405 Not Allowed");
}
return call_user_func_array($route['callback'], $matches);
} else {
$is_match++;
}
}
if ($is_match == $this->routeCount) {
throw new Exception("404 Not Found");
}
}
}
//autoload
// spl_autoload_register(function ($class_name) {
// require_once __DIR__ . '/' . str_replace('\\', '/', $class_name) . '.php';
// });
路由配置文件
config/route.php
<?php
return [
[
['GET'],
'/',
[new App\Index, 'index'],
],
[
['GET'],
'/search',
[new App\Index, 'search'],
],
[
['GET'],
'/tool-[id][/]',
[new App\Index, 'tool'],
],
[
['GET'],
'/tool-[id]',
[new App\Index, 'tool'],
],
[
['GET'],
'/category-[cid].html',
[new App\Index, 'category'],
],
[
['PUT,GET'],
'/hello',
function () {
echo 'Hello AmazePHP!';
},
],
[
['GET'],
'/hello2',
'callbackFunction',
],
[
['GET'],
'/hello44.php',
function () {
include 'App/aaaaa.php';
},
],
[
['GET'],
'/hello3/[id]',
[new App\Foo, 'bar'],////object, method
],
[
['GET'],
'/a/[uid]/b[/pid]',
['App\myclass', 'say_hello'],//static method
],
[
['GET,POST'],
'/users',
function () {
echo 'post AmazePHP';
},
],
[
['*'],
'/users/[uid]/posts/[pid]',
function ($uid, $pid = 99) {
var_dump($uid, $pid);
},
],
];
使用方法
index.php
include 'lib/Router.php';
include 'config/route.php';
$router = new Router();
foreach (config('route') as $key => $value) {
$router->addRoute($value[0][0], $value[1], $value[2]);
}
$router->doRouting();
评论 (0)