企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # 简介 一般情况下,Yii应用生成和接受形如`http://www.domain.com/index.php?r=post/view&id=1`的URL。这个URL分成几个部分: * 表示主机信息的`http://www.domain.com` * 表示入口脚本的`index.php` * 表示路由的`r=post/view` * 表示普通查询参数的`id=1` ## 隐藏入口文件 * Nginx位置 ~~~ location / { try_files $uri $uri/ /index.php?$args; } ~~~ * Apache配置文件(放在入门文件同级目录) ~~~ RewriteEngine on # 如果是一个目录或者文件,就访问目录或文件 RewriteCond %{REQUEST_FILENAME} !-d # 如果文件存在,就直接访问文件,不进行下面的RewriteRule RewriteCond %{REQUEST_FILENAME} !-f RewriteRule . index.php ~~~ > 另外服务器需要开启`rewrite`模块。 ## 配置UrlManager组件 打开`@app/config/main.php`中的`components`下面添加以下代码,如果想在全局生效可以将配置直接写入`common`模块下。 ~~~ 'components'=>[ ... 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'suffix' => '.html', // 伪后缀 'rules'=>[ 'article/<id:\d+>' => 'article/view', // 文章详情 'articles/<country_id:\d+>' => 'article/index', // 文章列表 'a1/<id:\d+>' => 'site/index', ], ], ... ], ~~~ > 详细页面,未优化前访问路径为文章[http://www.domain.com/index.php?r=article/detail.html&id=1](http://www.domain.com/index.php?r=article/detail.html&id=1),优化后访问路径为:[http://www.domain.com.cn/article/1390.html](http://www.domain.com.cn/article/1390.html) > 文章列表页面修改前为:[http://www.domain.com.cn/article/index.html?country\_id=1](http://www.domain.com.cn/article/index.html?country_id=1),优化后访问路径变为:[http://dev.welltrend.com.cn/articles/1.html](http://dev.welltrend.com.cn/articles/1.html) 请按照我下面这样来配置urlManager组件: ~~~php 'urlManager' => [ 'enablePrettyUrl' => true, //开启伪静态URL模式 'showScriptName' => false, //生成的网址里不带入口脚本名称 'enableStrictParsing' => true, //开启严格伪静态模式 'rules' => [ //伪静态规则配置,下面会讲解如何填写 ], ], ~~~ 好了,估计`?r=test/abc`这样的URL一旦访问时就会找不到页面而报404错误了,说明已经成功开启了伪静态模式 接下来我们添加一个URL白名单让它路由到test控制器的abc方法 上面增加urlManager组件的配置后,里面有个rules属性,值是一个数组,这里就是放URL白名单的地方了 比如我们要实现`/uiui.html`这个网址访问到test控制器的abc方法,就这样添加rules内容: ~~~php 'rules' => [ 'uiui.html' => 'test/abc', ], ~~~ # 在伪静态中传递GET参数 我们用`/uiui.html`这样的伪静态来取代了`/?r=test/abc`的网址形式 那么又如何表达`/?r=test/abc&userId=123`呢?难道是`/uiui123.html`这样吗?不行不行 其实简单地做,就可以这样写:`/uiui.html?userId=123`,这样控制器里依然可以收到参数,不信你试试`Yii::$app->request->get('userId')` 但一般情况下我们项目中都尽量把GET参数也隐藏在伪静态之中,比如实现 `/uiui7788.html`就相当于`/?r=test/abc&userId=7788`的效果,配置办法如下: ~~~php 'rules' => [ 'uiui<userId:\d+>.html' => 'test/abc', ], ~~~ 然后你试试 ~~~php echo Url::to(['test/abc', 'userId' => 7788]); ~~~ 就能看到输出`/uiui7788.html`了 # rules的key写法简介 这里需要一些正则表达式的知识基础,反正里面就是增加`<`和`>`这两个符号,表达这块区域要套一个参数进来 然后以参数的名称加`:`号开头,比如`userId:`这样Url::to方法的`'userId' => 值`才能知道它要生成到伪静态的哪个位置上 而`:`号后面的`\d+`表示当user\_id的值是数字的时候才可以生成,否则的话,比如`'userId' => 'abc'`这样的参数放在to方法里 由于值是字符串abc而不是一个数字,所以无法跟rules里的`\d+`(数字)匹配,不会生成预想中的`/uiuiabc.html`,如果要实现这样的话,必须将`\d+`改成`\w+`(英数字下划线),如果不熟悉正则基础的去恶补知识吧 而通常情况下rules配置中我也最常用的就是`\d+`和`\w+`这两个正则匹配符 # 复杂点的多参数伪静态 多个参数时其实也很容易理解,看看: `'uiui<userId:\d+><userName:\w+>-balabala<age:\d{2}><type:\d><width:\d+>-<height:\d+>.html' => 'test/abc'` 这里一共有6个参数,userId、userName、age、type、width和height,其中age只匹配2位数字,type只匹配一位数字 ~~~php echo Url::to(['test/abc', 'userId' => 65535, 'userName' => 'jay', 'age' => 18, 'type' => 4, 'width' => 200, 'height' => 100, ]); ~~~ 结果就生成了“**[http://xxx.com/uiui65535jay-balabala184200-100.html](http://xxx.com/uiui65535jay-balabala184200-100.html)**” 对了你有没有发现,test控制器不用建立abc方法也能生成?其实生成URL只是检查rules配置,匹配了就生成,它不管你有没有控制器方法(学过其它框架的话也很清楚,这个不新鲜了) 这个URL代入get参数后就是 ~~~php $_GET = [ 'userId' => 45678, 'userName' => 'kkqbx', 'age' => 18, 'type' => 2, 'width' => 1024, 'height' => 768, ]; ~~~