• ThinkPHP中URL解析原理,以及URL路由使用教程!


    几个概念:

    THINKPHP 是一个MVC框架,使用PATHINFO解析出分组名,模块名,方法名,以及参数。

    PATHINFO:就是 http://localhost/index.php/Home/Index/index/a/1/b/2?c=3 中的红色部分,注意,c=3并不是pathinfo的一部分,它是一个query参数。PATHINFO指的是URL中的路径实际上不存在的时候,apache或nginx等通过一定的手段将这个不存在路径保存到环境变量 $_SERVER['PATH_INFO']中,也可以将它转化为$_GET['s']参数,TP也可以识别。
    也就是说当你访问THINKPHP项目的时候,你实际上访问的只是入口文件index.php ,不管你后面有多长的路径,都是实际不存在的,转化成PATHINFO或$_GET['s']了而已。

    那么THINKPHP就是根据PATHINFO,从中提取出 分组名,模块名,方法名,以及将剩余的部分转化为$_GET变量,比如TP从PATHINFO字符串中提取'Home'字符串,将其保存到$_GET['g'] ,$_GET['m']='Index' ;$_GET['a']='index'  ;$_GET['a']=1  ;$_GET['b']=2。不信你可以随便在某个模块方法下 dump('$_GET')看看。

    之后Tp就是根据$_GET['g'],$_GET['m'],$_GET['a']来加载实例化对应分组下的模块类,并执行对应的方法。

    关于URL详细的解析流程,请看 ThinkPHP/Lib/Core/Dispatcher.class.php 核心类。



    URL路由:

    URL路由--Url Router,指的是,在TP进行常规url解析之前,先检测路由,如果发现有路由规则匹配当前的PATHINFO,那么URL解析则交给路由处理。

    路由规则是由多条 rule=>router 规则组成的数组。

    路由处理过程大概如下:

    1.遍历路由规则rule,与当前PATHINFO字符串进行匹配,如果合法,则从PATHINFO中取出所需要的字符串。

    2.路由中每条规则对应一个router,router中指定对应的模块以及方法,模块和方法可以用第1步中匹配到的字符串进行动态替代。

    3.将剩余的参数都解析并写入到$_GET中。


    路由规则:

    首先在配置文件中开启路由,"URL_ROUTER_ON"=>true;
    然后定义路由规则,路由规则也在配置文件中,参数名为 URL_ROUTE_RULES ,它是一个数组。
    假设我们打开一个url:http://localhost/index.php/ list/2/p/1 ,我们需要访问id为1分类列表页,并且p是页码,第一页。
    PATHINFO字符串为: list/2/p/1 
    我们需要将它定位到 listAction.class.php 模块中的 index方法,以及将p作为分页参数写入到$_GET中
    定义路由:
    'URL_ROUTE_RULES'=>array(
    'list/:id/p/:p'=>'Home/list/index'
    ),
    这样PATHINFO中的2将被写入到$_GET['id']=2, 同时 p 对应$_GET['p']=1 ,规则重定向到Home分组下的list模块index方法,我们只需要在index方法中直接获取$_GET['id'],以及$_GET['p']即可,实际访问效果等同于  http://localhost/index.php/Home/list/index?id=2&p=1
    假如我们要严格限定id和p的类型是数字,那么我们应该这样做
    'list/:id d/p/:p d'=>'Home/list/index'
    d表示数字类型。

    复杂一点的,假如PATHINFO为   del/10 。要调用article模块下的del方法,并将10作为id传递给它
    规则应该这样写
    “:a/:idd”=>'Home/article/ :1'
    首先,将del这一段作为一个变量去匹配,:a :b都可以,10也作为一个变量,指定为:id 并且类型要求是整型。在右侧router中,通过:1可以使用左侧第一个变量,:2 :3依次类推。
    再假设,我们禁止匹配 add/10中的add,规则只需要稍加改动,如下:
    “:a^add/:idd”=>'Home/article/ :1'
    如果要禁止多个关键词,则只需要用 |拼接,比如 ^add|del|get 

    如果右侧router默认需要带有参数,可以直接将参数加在?后面,比如
    “:a^add/:idd”=>'Home/article/ :1?p=1'
    也可以将右侧router写成数组形式,比如
    “:a^add/:idd”=>array('Home/article/:1','p=1&p1=2&p3=3')

    如果你需要 完整匹配整个PATHINFO,只需要在rule的结尾加上 $,比如
    list/:id$ 可以匹配 list/10,但是无法匹配list/10/p/1
    把$拿掉则都可以匹配。


    上面所讲的都是我们程序内部重定向,实际URL并不会发生跳转,如果我们想做一个redirect的跳转,只需要右侧router以http://开头或者以 '/' 开头即可。

    比如
    'list/:id'=>'/artlist/:1' 
    这样当我们访问 http://localhost/list/10的时候,浏览器会发生跳转,跳转到 http://localhost/artlist/10

    以上是TP自定定义的一些规则,那么当以上规则无法满足你的复杂需求时怎么办? 正则路由可以帮助你 。

    正则路由与普通路由的区别是,左侧rule不需要记住复杂的语法,我们只需要根据正则语法,直接匹配PATHINFO,右侧通过 :1 :2 :3调用即可。

    比如
    '/^list/(d+)/is'=>'Home/artlist/index?id=:1'

    注意事项:
    1.路由不会循环匹配,当匹配一次以后将跳出循环。
    2.当路由中同时包含 ^排除关键字 和 指定类型的时候,应当将 ^放在前面,比如 :d^add|dels  




  • 相关阅读:
    win10开机自启脚本
    centos7安装redis
    oracle安装
    Python进程和线程实例详解
    sonar+postgresql
    centos7更换下载源
    Python强大的日志模块logging
    centos7切换图形界面
    centos7安装mysql5.7
    Python正则表达式大全
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3186884.html
Copyright © 2020-2023  润新知