用php做一个简易的路由

index.php

复制代码
<?php
echo '<pre>$_REQUEST<br>';

print_r($_REQUEST);
// print_r($_SERVER);
 
$path_info = $_SERVER['PATH_INFO'];
$REQUEST_URI = $_SERVER['REQUEST_URI'];

// echo '$path_info='.$path_info;
// echo '$REQUEST_URI='.$REQUEST_URI;

$real_url = $_REQUEST['real_url'] ?? '';
$real_url = trim($real_url, '/');

$arr_url = explode('/', $real_url);
 

echo '<br>$real_url='.$real_url.'<br>arr_url=';
print_r($arr_url);

echo '<br>==========================================<br>';
$routes = [
    'about' => 'AboutController@index',
    'user/get/{username}' => 'UserController@get',
    'user/set/{user_id}' => 'UserController@set',
    'user/del/{user_id}' => 'UserController@del',
    'user/add' => 'UserController@add'
]; 

echo '路由表<br>';
print_r($routes);

echo '<br>==========================================<br>';

$controllerName = $arr_url[0];
$controllerNameLow = strtolower($controllerName);
 
$t_ok_path = '';
$t_ok_router =  '';

foreach($routes as $route_path => $t_router_controller){

    // echo '$route_path='.$route_path.', $t_router_controller='.$t_router_controller.'<br>';

    $arr_route_path = explode('/', $route_path);

    // print_r($arr_route_path); 

    $t_is_match = true;

    foreach($arr_route_path as $path_idx => $t_path){
        // echo "第{$path_idx}段路径<br>";
        $t_lower_path = strtolower($t_path);
        $t_seg_url = $arr_url[$path_idx];
        $t_seg_url_low = strtolower($t_seg_url);
     
        $is_dyn_param = strpos($t_path, '{') !== false;
        if($is_dyn_param){
            continue;
        }

        if($t_lower_path != $t_seg_url_low){
            $t_is_match = false; 
            // echo $t_lower_path . ':'. $t_seg_url_low . '不匹配<br>';
            break; 
        } 
    }

    if(!$t_is_match){
        continue;
    }else{
        $t_ok_path = $route_path;
        $t_ok_router =  $t_router_controller;
        // echo '匹配到路径 = ' .$t_ok_path.', router='. $t_ok_router.'<br>';
        break;
    }
}

if(!$t_ok_path){
    $t_msg = "<br><h1 style='color:red; font-weight:bold;'>404 not found: {$controllerName}</h1>";
    exit($t_msg);
}

echo '匹配到路径 = '.$t_ok_path.'<br>';
echo '匹配到控制器 = '.$t_ok_router.'<br>';
 
$arr_ok_router = explode('@', $t_ok_router);
$realControllerName = $arr_ok_router[0];

$actionName = $arr_ok_router[1];
if(!$actionName){
    $actionName = 'index';
}

$arr_path = explode('/', $t_ok_path);

 $arr_param = [];
foreach($arr_path as $path_idx => $t_path){
    $t_val = $arr_url[$path_idx] ?? '';
    //动态参数
    if(strpos($t_path, '{') !== false 
        && strpos($t_path, '}') !== false){
        $t_param_name = trim($t_path, '{}');
       
        $arr_param[$t_param_name] =  $t_val;
    }else{
    //    $arr_param[] =  $t_val;
    }
}
 
if($arr_param){
    $arr_param = [$arr_param];
}else{
    $t_count = count($arr_path);

    $arr_param = array_slice($arr_url, $t_count+1);
}

echo ' $arr_param =';
print_r( $arr_param );

include_once "controller/{$realControllerName}.class.php";
$t_controller  = new $realControllerName();
call_user_func_array([$t_controller, $actionName], $arr_param);

controller/UserController.class.php

复制代码
<?php

class UserController  {
    public function index() {
          echo 'index user';
    }

   public function get($v_param) {
        echo '<pre><h1 style="color:blue;">in UserController.get()</h1> '; 
        echo '<br>v_param<br>';
        print_r($v_param);
        // echo '<br>_REQUEST<br>';
        // print_r($_REQUEST);

        // $v_name = $_REQUEST['name'] ?? '';
        $v_name = $v_param['username'] ?? '';
        $v_name = trim($v_name);

        if(!$v_name){
            exit('username为空');
        }
        $arr_user = [
            'msk' => ['name'=>'马斯克', 'prop'=>'CEO'],
            'lxn' => ['name'=>'罗西尼', 'prop'=>'CFO'],
            'wzy' => ['name'=>'王志远', 'prop'=>'CTO'],
            'zxy' => ['name'=>'张晓宇', 'prop'=>'COO'],

        ];

        $user_info = $arr_user[$v_name] ?? [];
        if(!$user_info){
            $t_msg = "<div style='color:red'>不存在用户: {$v_name}</div>";
            exit($t_msg);
        }

        echo '用户详情:' . print_r($user_info,1);
   
    }
    public function set($v_param) {
        echo '<pre><h1 style="color:blue;">in UserController.set()</h1>'; 
        echo '<br>v_param<br>';
        print_r($v_param);
    
        $v_user_id = $v_param['user_id'] ?? '';
        $v_user_id = trim($v_user_id);

        echo '用户id:' . $v_user_id;
    }
}

controller/AboutController.class.php

复制代码
<?php

class AboutController  {
    public function index() {
        echo '这是关于页面' . PHP_EOL;

    }

}

nginx的配置:

复制代码
server {
        listen        80;
        server_name  www.myroute.cn;
        root   "D:/php_projects/myroute";
        location / {
            index index.php index.html error/index.html;
            error_page 400 /error/400.html;
            error_page 403 /error/403.html;
            error_page 404 /error/404.html;
            error_page 500 /error/500.html;
            error_page 501 /error/501.html;
            error_page 502 /error/502.html;
            error_page 503 /error/503.html;
            error_page 504 /error/504.html;
            error_page 505 /error/505.html;
            error_page 506 /error/506.html;
            error_page 507 /error/507.html;
            error_page 509 /error/509.html;
            error_page 510 /error/510.html;
            include D:/php_projects/myroute/nginx.htaccess;
            autoindex  off;
        }
        location ~ \.php(.*)$ {
            fastcgi_pass   127.0.0.1:9002;
            fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }
}

D:/php_projects/myroute/nginx.htaccess

复制代码
try_files $uri $uri /index.php?real_url=$uri&$args;

如果是用apache, 则.htaccess内容:

复制代码
<IfModule mod_rewrite.c>
    RewriteEngine On

    # 如果请求的不是一个真实存在的文件
    RewriteCond %{REQUEST_FILENAME} !-f
    # 如果请求的不是一个真实存在的目录
    RewriteCond %{REQUEST_FILENAME} !-d
    # 将请求重写到 index.php,并传递 real_url 和原有的查询字符串
    RewriteRule ^(.*)$ index.php?real_url=/$1 [QSA,L]
</IfModule>

跑一下 : http://www.myroute.cn/user/get/lxn

复制代码
$_REQUEST
Array
(
    [real_url] => /user/get/lxn
)

$real_url=user/get/lxn
arr_url=Array
(
    [0] => user
    [1] => get
    [2] => lxn
)

==========================================
路由表
Array
(
    [about] => AboutController@index
    [user/get/{username}] => UserController@get
    [user/set/{user_id}] => UserController@set
    [user/del/{user_id}] => UserController@del
    [user/add] => UserController@add
)

==========================================
匹配到路径 = user/get/{username}
匹配到控制器 = UserController@get
 $arr_param =Array
(
    [0] => Array
        (
            [username] => lxn
        )

)
in UserController.get()
 
v_param
Array
(
    [username] => lxn
)
用户详情:Array
(
    [name] => 罗西尼
    [prop] => CFO
)

http://www.myroute.cn/user/set/lxn

复制代码
$_REQUEST
Array
(
    [real_url] => /user/set/lxn
)

$real_url=user/set/lxn
arr_url=Array
(
    [0] => user
    [1] => set
    [2] => lxn
)

==========================================
路由表
Array
(
    [about] => AboutController@index
    [user/get/{username}] => UserController@get
    [user/set/{user_id}] => UserController@set
    [user/del/{user_id}] => UserController@del
    [user/add] => UserController@add
)

==========================================
匹配到路径 = user/set/{user_id}
匹配到控制器 = UserController@set
 $arr_param =Array
(
    [0] => Array
        (
            [user_id] => lxn
        )

)
in UserController.set()

v_param
Array
(
    [user_id] => lxn
)
用户id:lxn

http://www.myroute.cn/about

复制代码
$_REQUEST
Array
(
    [real_url] => /about
)

$real_url=about
arr_url=Array
(
    [0] => about
)

==========================================
路由表
Array
(
    [about] => AboutController@index
    [user/get/{username}] => UserController@get
    [user/set/{user_id}] => UserController@set
    [user/del/{user_id}] => UserController@del
    [user/add] => UserController@add
)

==========================================
匹配到路径 = about
匹配到控制器 = AboutController@index
 $arr_param =Array
(
)
这是关于页面

http://www.myroute.cn/index.php?real_url=user/add/mmm

add接口未实现,报错:

复制代码
$_REQUEST
Array
(
    [real_url] => user/add/mmm
)

$real_url=user/add/mmm
arr_url=Array
(
    [0] => user
    [1] => add
    [2] => mmm
)

==========================================
路由表
Array
(
    [about] => AboutController@index
    [user/get/{username}] => UserController@get
    [user/set/{user_id}] => UserController@set
    [user/del/{user_id}] => UserController@del
    [user/add] => UserController@add
)

==========================================
匹配到路径 = user/add
匹配到控制器 = UserController@add
 $arr_param =Array
(
)


Warning:  call_user_func_array() expects parameter 1 to be a valid callback, class 'UserController' does not have a method 'add' in D:\php_projects\myroute\index.php on line 125
相关推荐
老六ip加速器12 小时前
手机ip隔离方法
tcp/ip·智能手机·php
rockmelodies15 小时前
【PHP7内核剖析】-1.3 FPM
php
真正的醒悟19 小时前
上网管理行为-ISP路由部署
服务器·php·接口隔离原则
张晓~183399481211 天前
短视频矩阵源码-视频剪辑+AI智能体开发接入技术分享
c语言·c++·人工智能·矩阵·c#·php·音视频
2zcode1 天前
基于Matlab可见光通信系统中OOK调制的误码率性能建模与分析
算法·matlab·php
rockmelodies1 天前
【PHP7内核剖析】-1.1 PHP概述
开发语言·php
Codingwiz_Joy1 天前
Day43 PHP(mysql不同注入类型、mysql不同注入点、mysql传输不同数据类型 )
网络安全·php·安全性测试
rockmelodies1 天前
【PHP7内核剖析】-1.2 执行流程
php
ONLYOFFICE2 天前
【技术教程】如何将文档编辑器集成至用PHP编写的Web应用程序中
编辑器·php·onlyoffice