ThinkPHP入门-URL和路由

ThinkPHP入门-URL和路由

  1. 参考:ThinkPHP5快速入门-URL和路由。
  2. 以下为个人看文档的总结,背不时之需,需要的请转1中的参考文献。
  3. 学习的时候以5.1版本作为学习的版本。
  4. URL生成的部分还没有理解。
  5. 侵删

一、URL访问

  1. ThinkPHP采用单一入口模式访问应用,对应用的所有请求都定向到应用的入口文件,系统会从URL参数中解析当前请求的模块、控制器和操作,下面是一个标准的URL访问格式:
    http://domainName/index.php/模块/控制器/操作

  2. 其中index.php就称之为应用的入口文件(注意入口文件可以被隐藏,后面会提到),模块在ThinkPHP中的概念其实就是应用目录下面的子目录,而官方的规范是目录名小写,因此模块全部采用小写命名,无论URL是否开启大小写转换,模块名都会强制小写。

  3. 若访问Index控制器下的index方法的话,可以直接访问localhost/index.php,活着localhost/index.php/index/index/index

  4. 若访问Index控制器下的hello方法的话,需要完整的URL地址,localhost/index.php/index/index/hello

  5. 若方法有参数的话,看参数是否有默认值,有默认值为可选是否添加,添加可以直接添加在方法名后,
    localhost/index.php/index/index/hello
    localhost/index.php/index/index/hello/name/thinkphp

  6. 默认情况下,URL地址中的控制器和操作名是不区分大小写的,上下两者相同
    localhost/index.php/index/Index/Index
    localhost/index.php/index/INDEX/INDEX

  7. 如果你的控制器是驼峰的,例如定义一个HelloWorld控制器(application/index/controller/HelloWorld.php)注意文件名和控制器名要相同才行,正确的URL访问地址(该地址可以使用url方法生成)应该是:
    localhost/index.php/index/hello_world/index

  8. 如果直接使用HelloWorld在URL中描述控制器的话,将会提示该控制器不存在,可以在配置文件中进行修改 ‘url_convert’ => false,false表示关闭URL自动转换,支持驼峰直接访问控制器,关闭之后必须严格使用控制器的名称访问

二、参数传入

  1. 对于下面的方法分别为index和hello操作中,分别有不同的参数,

  2. 正常访问hello的URL为lcoalhost/index.php/index/index/hello,因为没有参数,则选择参数重的默认值,如果传入参数的话,则采用参数值,localhost/index.php/index/index/hello/name/thinkphp,输出结果为Hello,thinkphp!

  3. 对hello的方法增加参数情况下

    public function hello($name = 'World', $city = '')
    {
        return 'Hello,' . $name . '! You come from ' . $city . '.';
    }
    

    则该情况下的访问地址为lcoalhost/index.php/index/index/hello/name/thinkphp/city/shanghai,页面输出为 Hello,thinkphp! You come from shanghai.

  4. 对于3中的两个参数,可以根据传入的顺序不同的情况下来输出结果,并不影响最后结果,即:
    localhost/index.php/index/index/hello/city/shanghai/name/thinkphp
    localhost/index.php/index/index/hello?city=shanghai&name=thinkphp

  5. 还可以进一步简化URL,前提是必须明确参数的顺序代表的变量,首先调整配置文件中的url_param_type变量,改为按照参数的顺序获取,‘url_param_type’ => 1
    localhost/index.php/index/index/hello/thinkphp/shanghai,则页面的输出结果为:Hello,thinkphp! You come from shanghai.

  6. 一旦使用了url_param_type顺序获取,就不可以使用get或post。

三、隐藏index.php

  1. 主要目的是隐藏index.php,这个主要看你使用的是apache还是nginx,我这里使用的是mac下的自带的apache,很坎坷

  2. 其中mac自带的apache的文件的http.conf文件在/etc/apache2中,首先需要将mod_rewrite模块前面的#注释去除掉,然后文件中里面有三个AllowOverride All,我 都打开了。

  3. 在public下的index.php同级的目录下,会存在一个.htaccess文件,这个文件中需要配置内容,目的是隐藏index.php

    
    Options +FollowSymlinks -Multiviews
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
    
    
  4. 还有关于apache的phpstudy配置和nginx的配置方法等,请参考: 隐藏index.php

四、定义路由

  1. URL地址里面省略index模块,默认的URL比较长,可以通过路由的形式来简化URL的访问,在5.1的版本中,新增加了route的文件夹,里面可以定义route.php文件,可以在文件中添加路由的规则。
4.1 定义添加路由的方式1 - return[]中添加
  1. 可以在文件中的return数组中直接添加路由规则,该规则可以表示所有hello开头的并且带参数的访问都会直接到index控制器中的hello方法中。

    return [
    	// 添加路由规则 路由到 index控制器的hello操作方法
    	'hello/:name' => 'index/index/hello',
    ];
    
  2. 添加路由之后的访问地址变更为:
    localhost/hello/thinkphp,原地址的URL访问会失效变,localhost/index/index/hello/name/thinkphp非法请求。

  3. 此时在访问localhost/hello/thinkphp的时候可以任意访问,但是无论index控制器下的hello操作方法是否含有参数的情况下,直接访问localhost/hello都是不可以的,会产生模块不存在的错误。此时因为路由定义的为'hello/:name',表示hello中必须添加一个参数为name在hello的URL后面。

  4. 若是路由定义为'hello' => 'index/index/hello',,表示可以直接访问URL为localhost\hello即可,此时无法传入任何参数。

  5. 对3中的情况是因为路由没有正确匹配,注意此时添加的路由是需要参数的,修改路由规则即可,即将规则中的参数部分用[]将变量包起来,表示该变量可选,就可以正常的访问localhost/hello

    return [
    	// 路由参数 name 可选
    	'hello/[:name]' => 'index/hello',
    ];
    
4.2 定义添加路由的方式2 - 直接添加
  1. 需要引用use think\Route;
  2. 直接在return[]上方添加路由的规则即可,添加的效果和配置方式定义是一样的,Route::rule('hello/:name', index/index/hello);
  3. 无论使用那种定义添加路由的方式,配置文件都在config/app.php文件中。
4.3 完整匹配 - 访问URL
  1. 上文定义的只要是localhost/hello就可以访问,但是如果需要完整匹配的话,就需要在路由规则后面添加$结尾,表示当前的路由为完整匹配,要不的话,可以在路由后面添加多少东西都可以正常访问前面的hello操作方法

    return[
    	// 路由参数 name 可选
    	'hello/[:name]$' => 'index/index/hello',
    ]
    
  2. 在配置完整匹配后,表示只可以按照完整的路由进行访问,其他形式都不回匹配
    localhost/hello : 正确匹配
    localhost/hello/thinkphp : 正确匹配
    localhost/hello/thinkphp/val/value : 不会匹配

4.4 闭包定义 - 为某些特殊的场景定义路由规则
  1. 暂时没太理解这个功能是什么用的,但是这个可以直接返回,就不用在控制器中定义了,可以直接在路由中定义操作方法。使用方法可以使用return或者直接定义。

    use think/Route
    // 直接定义
    Route::rule('hello/[:name]', function($name) {
    	return 'Hello, ' . $name . '!';
    });
    
    // 使用return定义
    return [
    	// 定义闭包
    	'hello/[:name]' => function ($name) {
    		return 'Hello, ' . $name . '!';
    	},
    ]; 
    
  2. 可以通过访问localhost/hello/thinkphp地址,会输出Hello, thinkphp!

4.5 设置URL分隔符
  1. URL的分隔符就是指URL地址中的/可以修改为其他的符号,但是需要修改配置文件,配置文件在config/app.php中的pathinfo_depr,将该变量设置为想要的符号即可
    'pathinfo_depr' => '-',这样访问地址的就变为了
    localhost/hello-thinkphp
4.6 路由参数
  1. 路由可以根据路由参数来限制路由访问的请求类型或者URL后缀之类的条件,例如

    return [
    	// 定义理由的请求类型和后缀
    	'hello/[:name]' => ['index/index/hello', ['method' => 'get', 'ext' => 'html']],
    ];
    
  2. 上面定义的路由限制了必需是get请求,而且后缀必需是html的,所以访问的时候
    localhost/hello : 无效
    localhost/hello.html : 有效
    localhost/hello/thinkphp : 无效
    localhost/hello/thinkphp.html : 有效

  3. 具体的路由参数还需要参考完全开发手册中的路由参数一节ThinkPHP完全开发手册-路由-路由参数。

4.7 变量规则
  1. 可以定义复杂的路由规则来满足不同的路由变量,增加下面的控制器和操作方法

  2. 常规的思路是在return中添加路由规则,并可以通过下面的URL进行访问
    localhost/blog/5 // 访问id为5的内容
    localhost/blog/thinkphp // 访问name为thinkphp的内容
    localhost/blog/2015/05 // 访问2015年5月的归档内容

  3. 普通情况下在return[]中添加的形式

    return [
    	'blog/:year/:month' => ['index/blog/archive', ['method' => 'get'], ['year' => '\d{4}', 'month' => '\d{2}']],
    	'blog/:id' => ['index/blog/read', ['method' => 'get'], ['id' => '\d+']], 
    	'blog/:name' => ['index/blog/get', ['method' => 'get'], ['name' => '\w+']],
    ];
    
  4. 也可以对上面的路由进行简化,因为都是blog开头的路由,这种定义可以一定程度上提高路由的检测的效率。

    return [
    	'[blog]' => [
    		':year/:month' => ['index/blog/archive', ['method' => 'get'], ['year' => '\d{4}', 'month' => '\d{2}']],
    		':id' => ['index/blog/read', ['method' => 'get'], ['id' => '\d+']], 
    		':name' => ['index/blog/get', ['method' => 'get'], ['name' => '\w+']],
    	],		
    ];
    
    
4.8 复杂路由
  1. 有时候需要对URL做一些特殊的定制,例如如果同时支持下面的访问地址
    localhost/blog/thinkphp
    localhost/blog-2015-05

  2. 可以根据上面的访问形式来修改路由的定义的规则,对于blog--这样的非正常规范,需要使用<变量名>这样的变量定义方式,而不是:变量名方式。

    return [
        'blog/:id'            => ['blog/get', ['method' => 'get'], ['id' => '\d+']],
        'blog/:name'          => ['blog/read', ['method' => 'get'], ['name' => '\w+']],
        'blog--' => ['blog/archive', ['method' => 'get'], ['year' => '\d{4}', 'month' => '\d{2}']],
    ];
    
  3. 还可以将参数的定义规则提取出来,存放到全局,用来直接使用

    return [
        // 全局变量规则定义
        '__pattern__'         => [
            'name'  => '\w+',
            'id'    => '\d+',
            'year'  => '\d{4}',
            'month' => '\d{2}',
        ],
        // 路由规则定义
        'blog/:id'            => 'blog/get',
        'blog/:name'          => 'blog/read',
        'blog--' => 'blog/archive',
    ];
    
  4. __pattern__中定义的变量规则可以称为全局变量规则,在单个路由里面定义的称为局部变量规则,若同时定义了全局规则和局部规则,当前的局部规则会覆盖全局规则。

    return [
        // 全局变量规则
        '__pattern__'         => [
            'name'  => '\w+',
            'id'    => '\d+',
            'year'  => '\d{4}',
            'month' => '\d{2}',
        ],
    
        'blog/:id'            => 'blog/get',
        // 定义了局部变量规则
        'blog/:name'          => ['blog/read', ['method' => 'get'], ['name' => '\w{5,}']],	// 这里表示字母长度必需大于等于5个
        'blog--' => 'blog/archive',
    ];
    
  5. 在5.1中路由配置文件为单独的route/route.php,并且支持随意明明,都会自动加载,尽量建议使用注册路由的方式替代数组配置的方式

    use think\facade\Route;
    
    Route::get('blog/:id','blog/get');
    Route::get('blog/:name','blog/read');
    

五、URL生成

URL生成的目的,目前的理解为:

1.controller下的php文件生成路由如:$url= Url::build('blog/read', 'name='.$param);然后其他地方就可以直接调用$url
2.view下的html文件跳转指定地址如超链接里面内容为:{:url('blog/read', 'name='.$param)}

  1. 定义路由规则之后,我们可以通过Url类来方便的生成实际的URL地址(路由地址),针对上面的路由规则,我们可以用下面的方式生成URL地址。build方法的第一个参数使用路由定义中的完整路由地址。

    // 输出 blog/thinkphp
    Url::build('blog/read', 'name=thinkphp');
    Url::build('blog/read', ['name' => 'thinkphp']);
    // 输出 blog/5
    Url::build('blog/get', 'id=5');
    Url::build('blog/get', ['id' => 5]);
    // 输出 blog/2015/05
    Url::build('blog/archive', 'year=2015&month=05');
    Url::build('blog/archive', ['year' => '2015', 'month' => '05']);
    
  2. 可以使用系统提供的助手函数URL简化,
    url('blog/read', 'name=thinkphp'); 等效于 Url::build('blog/read', 'name=thinkphp');

  3. **?**若在模版文件中进行输出的话,可以使用助手函数,{:url('blog/read', 'name=thinkphp')}

  4. config/app.php中进行配置url_html_suffix参数的话,生成的URL地址会带上后缀
    'url_html_suffix' => 'html',
    生成的URL地址类似blog/thinkphp.htmlblog/2015/05.html

  5. 如果你的URL地址全部采用路由方式定义,也可以直接使用路由规则来定义URL生成
    url(’/blog/thinkphp’);
    Url::build(’/blog/8’);
    Url::build(’/blog/archive/2015/05’);

  6. 生成方法的第一个参数一定要和路由定义的路由地址保持一致,如果你的路由地址比较特殊,例如使用闭包定义的话,则需要手动给路由指定标识

    // 添加hello路由标识
    Route::rule(['hello','hello/:name'], function($name){
        return 'Hello,'.$name;
    });
    // 根据路由标识快速生成URL
    Url::build('hello', 'name=thinkphp');
    // 或者使用
    Url::build('hello', ['name' => 'thinkphp']);
    
  7. 5.1版本,你需要引入think\facade\Url才能使用静态方法调用,其它用法不变。高阶方法具体可参考ThinkPHP5路由完全指南

你可能感兴趣的:(PHP)