2

PHP单文件路由类

 1 year ago
source link: https://blog.p2hp.com/archives/10978
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Lenix Blog

Router.php

<?php
class Router
private $routes = [];
private $routeCount = 0;
public function addRoute($method, $url, $callback)
if ($url !== '/') {//去除url尾部斜杠
while ($url !== $url = rtrim($url, '/'));//不应该去除url尾部斜杠,以后要改
$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'];
$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\_\-]+/');
$replace = array('([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';
// });
<?php

class Router
{
    private $routes = [];
    private $routeCount = 0;

    public function addRoute($method, $url, $callback)
    {
        if ($url !== '/') {//去除url尾部斜杠
            while ($url !== $url = rtrim($url, '/'));//不应该去除url尾部斜杠,以后要改
        }

        $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'];

       

        $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\_\-]+/');
            $replace = array('([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);
<?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();
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();




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK