php路由原理_路由原理 · 人人商城详细开发文档 · 看云

[TOC]

看了前面的目录结构介绍,我们知道`mobile`目录是代表前端app,`web`目录是代表后台的。

现在举例一个链接地址:

[http://guli.com/app/index.php?i=4&c=entry&m=ewei\_shopv2&do=mobile&r=shop.category&mid=2985&v=159279](http://guli.com/app/index.php?i=4&c=entry&m=ewei_shopv2&do=mobile&r=shop.category&mid=2985&v=159279)

参数r前的链接是微擎的路由规则,具体参考微擎的官方文档教程,这里就不做解释了。链接中的

`r=shop.category&mid=2985&v=159279` ,其中的` r=shop.category`,这里是人人商城的路由访问地

址现在先看看人人商城路由的的路由加载原理:

**1**.路由一开始访问,首先进入的是 ` ewei_shopv2/site.php `文件,根据 参数 do 来访问后台,还是mobile前端,

而执行图中红框划着对应的方法

![](https://img.kancloud.cn/63/06/630648e824cd055c311882cbb182cb2b_536x379.png)

**2**.方法中的 m('route')->run(); ,是调用路由的加载, m('route') 是指加载 ewei_shopv2/core/model 目录下的

route.php,打开这个文件,就一个run方法,代码都是处理路由相关的,看以下代码注释

```

class Route_EweiShopV2Model {

function run($isweb = true)

{

global $_GPC, $_W;

//加载第三方类库插件

// autoload

if (version_compare(EWEI_SHOPV2_VERSION, '3.14.0', '>=')) {

@include_once EWEI_SHOPV2_PATH . 'vendor/autoload.php';

}

//page.php 文件是包含对加载,渲染模板的一些方法

require_once IA_ROOT . "/addons/ewei_shopv2/core/inc/page.php";

//判断是访问app端还是后台。加载对应文件,此2个文件都是处理加载插件,权限等

if ($isweb) {

require_once EWEI_SHOPV2_CORE . "inc/page_web.php";

require_once EWEI_SHOPV2_CORE . "inc/page_web_com.php";

} else{

require_once EWEI_SHOPV2_CORE . "inc/page_mobile.php";

require_once EWEI_SHOPV2_CORE . "inc/page_mobile_login.php";

}

//处理链接中的参数r

$r = str_replace("//", "/", trim($_GPC['r'], "/"));

$routes = explode('.', $r);

$segs = count($routes);

$method = "main";

$root = $isweb ? EWEI_SHOPV2_CORE_WEB : EWEI_SHOPV2_CORE_MOBILE;

$isMerch = false;

$isNewstore = false;

//如果参数r为空,则设置默认路由

if(strexists($_W['siteurl'] ,"web/merchant.php")) {

if(empty($r)) {

$r = "merch.manage";

$routes = explode('.', $r);

}

$isMerch = true;

$isplugin = true;

} else if(strexists($_W['siteurl'] ,"web/newstoreant.php")) {

if(empty($r)) {

$r = "newstore.manage";

$routes = explode('.', $r);

}

$isNewstore = true;

$isplugin = true;

} else{

$isplugin = !empty($r) && is_dir(EWEI_SHOPV2_PLUGIN . $routes[0]);

}

//判断参数r是否访问插件模块

if ($isplugin) {

if ($isweb) {

require_once EWEI_SHOPV2_CORE . "inc/page_web_plugin.php";

} else {

require_once EWEI_SHOPV2_CORE . "inc/page_mobile_plugin.php";

require_once EWEI_SHOPV2_CORE . "inc/page_mobile_plugin_login.php";

require_once EWEI_SHOPV2_CORE . "inc/page_mobile_plugin_pf.php";

}

//core目录为人人商城的核心目录

$_W['plugin'] = $routes[0];

$root = EWEI_SHOPV2_PLUGIN . $routes[0] . "/core/" . ( $isweb ? "web" : "mobile") . "/";

if($isMerch){

$_W['plugin'] ="merch";

$root = EWEI_SHOPV2_PLUGIN . "merch/core/web/manage/";

} else if($isNewstore){

$_W['plugin'] ="newstore";

$root = EWEI_SHOPV2_PLUGIN . "newstore/core/web/manage/";

}

else{

$routes = array_slice($routes, 1);

}

$segs = count($routes);

} else if($routes[0]=='system'){

require_once EWEI_SHOPV2_CORE . "inc/page_system.php";

}

//$segs 为参数r , 按"." 字符explode处理后得到的数组

switch ($segs) {

case 0: {

//数组个数为空访问默认首页

$file = $root . "index.php";

$class = "Index";

}

case 1: {

$file = $root . $routes[0] . ".php";

//数组个数为1个时访问指定模块

if (is_file($file)) {

$class = ucfirst($routes[0]);

} elseif (is_dir($root . $routes[0])) {

$file = $root . $routes[0] . "/index.php";

$class = "Index";

} else {

$method = $routes[0];

$file = $root . "index.php";

$class = "Index";

}

$_W['action'] = $routes[0];

}

break;

case 2: {

$_W['action'] = $routes[0] . "." . $routes[1];

$file = $root . $routes[0] . "/" . $routes[1] . ".php";

//数组个数为2时, 例如 r=order.list ,这里会判断 order/list 是否为一个目录,如果是,则会访问 order/list /index.php

//如果order/list 不是一个目录,list是一个文件,那就访问order/list,php

if (is_file($file)) {

$class = ucfirst($routes[1]);

} elseif (is_dir($root . $routes[0] . "/" . $routes[1])) {

$file = $root . $routes[0] . "/" . $routes[1] . "/index.php";

$class = "Index";

} else {

//又或者order不是目录,是一个文件

$file = $root . $routes[0] . ".php";

if (is_file($file)) {

$method = $routes[1];

$class = ucfirst($routes[0]);

} elseif (is_dir($root . $routes[0])) {

$method = $routes[1];

$file = $root . $routes[0] . "/index.php";

$class = "Index";

} else {

$file = $root . "index.php";

$class = "Index";

}

}

$_W['action'] = $routes[0] . "." . $routes[1];

break;

}

case 3: {

//和上面的 数组个数为2时 处理情况一样,不在赘述

$_W['action'] = $routes[0] . "." . $routes[1] . "." . $routes[2];

$file = $root . $routes[0] . "/" . $routes[1] . "/" . $routes[2] . ".php";

if (is_file($file)) {

$class = ucfirst($routes[2]);

} elseif (is_dir($root . $routes[0] . "/" . $routes[1] . "/" . $routes[2])) {

$file = $root . $routes[0] . "/" . $routes[1] . "/" . $routes[2] . "/index.php";

$class = "Index";

} else {

$method = $routes[2];

$file = $root . $routes[0] . "/" . $routes[1] . ".php";

if (is_file($file)) {

$class = ucfirst($routes[1]);

} elseif (is_dir($root . $routes[0] . "/" . $routes[1])) {

$file = $root . $routes[0] . "/" . $routes[1] . "/index.php";

$class = "Index";

}

$_W['action'] = $routes[0] . "." . $routes[1];

}

break;

}

case 4: {

$_W['action'] = $routes[0] . "." . $routes[1] . "." . $routes[2];

$method = $routes[3];

$class = ucfirst($routes[2]);

$file = $root . $routes[0] . "/" . $routes[1] . "/" . $routes[2] . ".php";

break;

}

}

if (!is_file($file)) {

show_message("未找到控制器 {$r}");

}

$_W['routes'] = $r;

$_W['isplugin'] = $isplugin;

$_W['controller'] = $routes[0];

//读取网站整体配置,保存在cache

$global_set= m('cache')->getArray('globalset');

if(empty($global_set)){

$global_set = m('common')->setGlobalSet();

}

if(!is_array($global_set)){

$global_set = array();

}

empty($global_set['trade']['credittext']) && $global_set['trade']['credittext'] = "积分";

empty($global_set['trade']['moneytext']) && $global_set['trade']['moneytext'] = "余额";

$GLOBALS["_S"] = $_W['shopset'] = $global_set;

include $file;

//判断访问通过app端还是pc的,

if (isset($_GPC['r']) && strpos($_GPC['r'], 'pc') !== false) {

//Controller为pc端的控制器

$class = ucfirst($class) . "Controller";

} else {

//EweiShopV2Page为app端的控制器

$class = ucfirst($class) . "_EweiShopV2Page";

}

//执行已加载对应控制器的方法

$instance = new $class();

if (!method_exists($instance, $method)) {

show_message("控制器 {$_W['controller']} 方法 {$method} 未找到!");

}

$response = $instance->$method();

if (!empty($response)) {

echo $response;

}

die;

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TP(ThinkPHP)框架的路由解析原理可以简单概括为以下三个步骤: 1. 获取请求信息:TP框架通过PHP的超全局变量`$_SERVER`和`$_REQUEST`获取当前请求的URL、请求方法等信息。 2. 解析路由规则:TP框架会根据路由规则解析当前请求的控制器、方法以及传递给方法的参数。路由规则可以通过配置文件或者注解方式定义。 3. 执行控制器方法:TP框架根据解析出来的控制器、方法和参数,执行相应的业务逻辑。 具体来说,TP框架的路由解析过程如下: 1. 获取请求信息: TP框架通过`$_SERVER`变量获取当前请求的URL和请求方法,例如: ``` $requestUri = $_SERVER['REQUEST_URI']; // 获取请求的URL $requestMethod = $_SERVER['REQUEST_METHOD']; // 获取请求的方法 ``` 2. 解析路由规则: TP框架支持多种路由规则,例如: - URL模式:`/:controller/:action/:id`,解析后会得到控制器名、方法名和参数`id`; - 路由规则:`'user/:id' => 'index/user/read'`,将`user/123`请求解析为`Index`控制器的`user`方法,并传递参数`id=123`; - 注解方式:使用注解标记控制器和方法,例如: ```php /** * @route('hello/:name') */ public function hello($name) { echo 'Hello '.$name; } ``` 以上是TP框架路由的基本使用方法,具体可以参考官方文档。 3. 执行控制器方法: TP框架根据解析出来的控制器名、方法名和参数,执行相应的业务逻辑。例如: ```php // 根据控制器名和方法名,实例化控制器对象并调用方法 $controller = '\\app\\index\\controller\\'.$controllerName; $instance = new $controller(); $instance->$actionName($param); ``` 注意,TP框架还支持路由缓存等优化方式,可以提高路由解析效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值