php 路由实现_php实现路由接口 | ZJINH-Blog

php简单路由实现

# 需求

实现自定义url对应控制器及内部方法,友好url传参

# 服务器配置 nginx nginx.conf

location / {

rewrite ^/service/(.*)$ /index.php?_url=$1 last;

}apache .htaccess

RewriteEngine On

RewriteRule ^$ index.php?_url= [QSA,PT,L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?_url=$1 [QSA,L]

以上配置文件是实现路由的关键,会将用户访问的 service/abc 在服务器转换成 service/index.php?_url=abc,从而实现自定义路由

# 关键源码解析

$route=include "web.php";//在此处引入路由文件

class Router

{

private $route;//一个私有变量

public function __construct(array $route) //执行一个构造方法

{

$this->route = $route; //将路由赋值到类里

}

public function parse($url)

{

if(empty($url)) {//如果是空的,则访问默认的路由

list($controller, $action) = explode('@', $this->route['_DEFAULT_']);

return array(

'controller' => $controller,

'action' => $action,

'params' => array(),

);

}

//这里定义了实现 any 和num过滤的正则

$trans = array(

':any' => '[^/]+',

':num' => '[0-9]+'

);

//循环查找路由配置文件,匹配路由和控制器方法

foreach($this->route as $u => $d) {

$pattern = '#^' . strtr($u, $trans) . '$#';//过滤参数

if(preg_match($pattern, $url, $params)) {

list($controller, $action) = explode('@', $d);//将切割后的变量使用list赋值

array_shift($params);

return array(//这里返回即将执行的控制器、方法、参数

'controller' => $controller,

'action' => $action,

'params' => $params,

);

}

}

//如果找不到则返回404

header("HTTP/1.0 404 Not Found");

exit('

Sorry, the page you are looking for could not be found.
This URL could not be found in the route.
Please check your request address or your defined route param.
');

}

}

$r = new Router($route);//启动执行路由类

$arr = $r->parse($_GET['_url']);//获取url上_url后的参数 也就是访问的路由,将其分割找出控制器和方法

require('Controller/'.$arr['controller'] . '.php');

//执行控制器的功能

$dispatcher = new $arr['controller'];//引入对应的控制器

call_user_func_array(array($dispatcher, $arr['action']), $arr['params']);//调用控制器方法并传入参数

# 源码结构

├── Controller # 控制权目录

├── index.php # 路由入口

├── web.php #路由配置文件

└── .htaccess apache服务器伪静态配置文件

# 使用方法

# PHP环境配置(修改php.ini) 建议环境PHP7+

打开exif扩展

打开com_dotnet扩展

设置session.auto_start = 1

设置post_max_size = 500M

# MYSQL环境配置(修改.ini)

#此处是设置mysql5.7允许使用group_by

在my.ini 的[mysqld]下添加sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

# Apache环境配置(修改.http.conf)

打开LoadModule rewrite_module modules/mod_rewrite.so 如果前面有#去掉#

设置 Options Index FollowSymLinks Includes ExecCGI 为 Options FollowSymLinks Includes ExecCGI

# 项目内环境配置

修改service下server.php(socket服务)的$conf变量

修改service\Controller下ServerController.php(数据服务)的$conf变量

$conf=[

"HOST"=>"127.0.0.1", 为数据库所在地址

"PORT"=>"3306", 为数据库端口

"DATABASE"=>"db", 为数据库名

"USERNAME"=>"root", 为数据库用户名

"PASSWORD"=>"123456", 为数据库密码

"ADDRESS"=>"/abc/123" 为项目绝对路径地址(index.php文件所在地址)

];

# 路由配置 路由配置文件在service下的web.php

路由写法为 'xx/test/(:any)'=>'Controller@function',

xx/test为url部分后面对应控制器及控制器内的方法

(:any)为路由参数,对应方法所需参数,可带多个(:any)为任何字符,(:num)为数字

例如配置了 'aa/test/(:any)/(:any)'=>'Controller@test1',test1需要接受两个参数,test后的(:any)则为传入test1方法的参数

在浏览器地址访问 http://domain.com/aa/test/123/666在test1方法里输出 则会接收到 123 666

# 部署成功效果

此时的地址不应该出现index.php

521219267877b24d0192206197874a07.png

# 访问你定义的路由

例如我定义了 'user/login' => 'UserController@login',这个地址将会访问用户控制器里的登录方法,这里使用了post传参,所以路由没有参数

在浏览器访问http://domain.com/user/login由于我返回了json,在浏览器看到的效果则是

246a766662a33690ea848d4e72b518ef.png

这里经过转义后则是

[{

msg: "密码错误",

state: "error"

}]

# 不存在的路由或缺少参数

同样访问上面的http://domain.com/user/login/abc不同的是在login后面多了/abc

那么浏览器将会显示

eac74db0ee6232bc50d55a01e6c17f3a.png

以上 便是一个路由系统简单的实现,下面是源码地址

# 源码

觉得好用的话 留个star呗

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值