YII自己的跳转很灵活。通常的MVC出现跳转的也不外乎:
(1)V->V 页面以前的跳转javascript
(2)C->V 正常的MVC方式php
(3)V->C 请求数据接口数据传参,我仍是通常都会用JS的ajax实现html
这三种也都逃不了YII特有的方法和PHP原生的方法实现java
首先针对于v->v这种页面直接跳转的方式,最多见的就是超连接。git
超连接在原生的写法中是直接写绝对地址或ur拼接。这种在YII中因为跳转基本是经过controller从中实现的,这边要注意其实这里仍是和v->c相似,url拼接的仍是相应规则的内容(不然不少有YII引入的样式表和JS都没法正常表现)github
原生写法web
<a href='index.php/index?data="abc" ' >
YII写法ajax
<a href="<?= URL::to('index','date'=>'abc') ?>" >
或更直接的PHP风格数组
<?=HTML::a('index','date'=>'abc') ?>
看的出来这里的URL就是C层转向V的地址,因此咱们的V->C层代码也不外乎这样服务器
再来看下c->v
这一步能够说是MVC的最经典的操做,通常其余框架比较常见的是SMARTY传至并访问。这里咱们要用的是YII的redner系列方法。例如最经常使用的
$this->render('index',[参数列表])
另外若是实现返回上一个页面的效果可使用:
Yii::$app->request->referrer
或者 Yii::$app->request->getReferre()
这里有几个tips:
1.对于render其实底层实现的就是renderContent。只是将页面的中间部分放入,包含YII的头部和底部,这里若是须要修改能够换位rendiect
2.在跳转的时候默认的是本控制器,若是须要其余控制器能够在前面多加一个“/”.好比我是经过DefaultController.php的index方法跳转当前页,若是我要去LoginController处理登陆业务的页面,我就须要“//login/login”
简单整理:
在yii2中,引入视图模版文件的4种方法的区别以下:
1)、“@app” 开头,“@app”是一个路径别名,对应站点根目录。好比项目路径为:E:/www/yii2/,引入为:$this->render('@app/views/site/about.php'),则对应的文件所在磁盘路径为:“E:/www/yii2/views/site/about.php”(能够用var_dump(Yii::getAlias('@app'));查看@app的值)。
2)、默认为控制器或小部件对应默认的路径,例如:SiteController.php中return $this->render(“about”) 对应到 @app/views/site/about.php (即:E:/www/yii2/views/site/about.php)。
3)、“//” 开头对应的视图文件路径为 @app/views/... ,例如 //site/about 对应到 @app/views/site/about.php 。
4)、“/”开头表示相对于当前views目录的位置,例如:若是当前模块为user,/site/about对应成@app/modules/user/views/site/about.php , 若是不是模块,/site/about对应 @app/views/site/about.php 。注意:“//”和“/”的区别在于,“//”至关于绝对路径,“/”至关于相对路径。具体对好比下:
控制器 | $this->render | 模版路径 |
E:/yii2/controllers/SiteController.php | //site/about | E:/yii2/views/site/about.php |
E:/yii2/modules/user/controllers/SiteController.php | //site/about | E:/yii2/views/site/about.php |
E:/yii2/controllers/SiteController.php | /site/about | E:/yii2/views/site/about.php |
E:/yii2/modules/user/controllers/SiteController.php | /site/about | E:/yii2/modules/user/views/site/about.php |
PS:若是不指定模版的后缀名,默认为”.php”。
3.$this在不一样地方的意义。在VIEW层的$this就是yii/web/view;在CONTROLLERyii/web/controller,因此不能够在view层用render跳转
4.对于URL**和HTML的用法
(1)YII有一些助手类,HTML是能够生成一些HTML代码的类。例如在上面实例中HTML::a就是生成了一个a标签。而对于这个的实现其实就是调用内部的HTML::tag。因此也能够直接用这个实现。举个例子:
Html::img( '/abc/image1.jpg', [ 'alt' => '头像' ] )
这个是一个生成HTML中img标签,框架在实现的函数:
public static function img($src, $options = []) { $options['src'] = Url::to($src); if (isset($options['srcset']) && is_array($options['srcset'])) { $srcset = []; foreach ($options['srcset'] as $descriptor => $url) { $srcset[] = Url::to($url) . ' ' . $descriptor; } $options['srcset'] = implode(',', $srcset); } if (!isset($options['alt'])) { $options['alt'] = ''; } return static::tag('img', '', $options); }
能够看到这里最后一行仍是返回一个静态的tag函数:
public static function tag($name, $content = '', $options = []) { if ($name === null || $name === false) { return $content; } $html = "<$name" . static::renderTagAttributes($options) . '>'; return isset(static::$voidElements[strtolower($name)]) ? $html : "$html$content</$name>"; }
因此也能够写做:
<?= Html::tag('img') ?>
后面也能够添加参数,可是注意第二个参数在img标签的时候为空,由于是图像标签没有文字内容。图片源和文字说明都是做为第三个参数填入的。HTML在生成标签的时候还有lable、button、input等等经常使用标签。
(2)HTML助手类在使用的时候,对于标签嵌套的时候要注意使用参数。例如在ul标签中嵌套li的时候,li的内容要防止编码要注意能够在ul()使用第二个参数:
public static function ul($items, $options = []) { $tag = ArrayHelper::remove($options, 'tag', 'ul'); $encode = ArrayHelper::remove($options, 'encode', true); $formatter = ArrayHelper::remove($options, 'item'); $separator = ArrayHelper::remove($options, 'separator', "\n"); $itemOptions = ArrayHelper::remove($options, 'itemOptions', []);
例如:
不想被转义就应该用Html::ul($arr, ['encode' => false]);
(3)Url 帮助类提供一系列的静态方法来帮助管理 URL。和HTML同样都是助手类,在使用的时候都须要use下该类。例如:use yii\helps\Url;
关于这个类比较经常使用的就是to和toRoute
(I)关于toRoute----获取某一地址
看下官网上的说法:
为了建立一个给定路由的 URL 地址,请使用 `Url::toRoute()`方法。 $url = Url::toRoute(['product/view', 'id' => 42]); 你能够指定一个字符串来做为路由,如: site/index 。若是想要指定将要被建立的 URL 的附加查询参数, 你一样可使用一个数组来做为路由。数组的格式须为: // generates: /index.php?r=site/index¶m1=value1¶m2=value2 ['site/index', 'param1' => 'value1', 'param2' => 'value2'] 若是你想要建立一个带有 anchor 的 URL ,你可使用一个带有 # 参数的数组。好比: // generates: /index.php?r=site/index¶m1=value1#name ['site/index', 'param1' => 'value1', '#' => 'name'] 一个路由既多是绝对的又多是相对的。一个绝对的路由之前导斜杠开头(如: /site/index), 而一个相对的路由则没有(好比: site/index 或者 index)。一个相对的路由将会按照以下规则转换为绝对路由: * 若是这个路由是一个空的字符串,将会使用当前 yii\web\Controller::route 做为路由; * 若是这个路由不带任何斜杠(好比 index ),它会被认为是当前控制器的一个 action ID, 而后将会把 yii\web\Controller::uniqueId 插入到路由前面。 * 若是这个路由不带前导斜杠(好比: site/index ),它会被认为是相对当前模块(module)的路由, 而后将会把 yii\base\Module::uniqueId 插入到路由前面。 如下是该方法的一些例子: // /index.php?r=site/index echo Url::toRoute('site/index'); // /index.php?r=site/index&src=ref1#name echo Url::toRoute(['site/index', 'src' => 'ref1', '#' => 'name']); // /index.php?r=post/edit&id=100 assume the alias "@postEdit" is defined as "post/edit" echo Url::toRoute(['@postEdit', 'id' => 100]); // http://www.example.com/index.php?r=site/index echo Url::toRoute('site/index', true); // https://www.example.com/index.php?r=site/index echo Url::toRoute('site/index', 'https');
稍做整理:有第二个参数且不是URL传递解析的内容就会得到绝对地址,也就是包含协议域名等部分的内容
1://获取某地址 - 相对路径
$url = Url::toRoute('site/index');
2://获取某地址 - 相对路径
$url = Url::toRoute('site/index', false);
说明: 等价于1 由于默认是false
3://获取某地址 - 相对路径
$url = Url::toRoute(['site/index', 'id' => 1]);
4://获取某地址的 - 绝对路径
$url = Url::toRoute('site/index', true);
5://获取某地址的 -绝对路径
$url = Url::toRoute('site/index', ['id' => 1]);
说明: 参数没有输出,说明,这种写法['id' => 1], 他当成了true,因此等价于4
6://获取某地址的 - 绝对路径 (传输协议-http)
$url = Url::toRoute('site/index', 'http');
7://获取某地址的 -绝对路径(传输协议-https)
$url = Url::toRoute('site/index', 'https');
(II)关于toRoute----建立一个基于给定参数的网址
一样看下官网的说法:
还有另一个方法 Url::to() 和 toRoute() 很是相似。这两个方法的惟一区别在于,前者要求一个路由必须用数组来指定。 若是传的参数为字符串,它将会被直接当作 URL 。 Url::to() 的第一个参数能够是: * 数组:将会调用 toRoute() 来生成URL。好比: ['site/index'], ['post/index', 'page' => 2] 。 详细用法请参考 toRoute() 。 * 带前导 @ 的字符串:它将会被当作别名, 对应的别名字符串将会返回。 * 空的字符串:当前请求的 URL 将会被返回; * 普通的字符串:返回自己。 如下是一些使用示例: // /index.php?r=site/index echo Url::to(['site/index']); // /index.php?r=site/index&src=ref1#name echo Url::to(['site/index', 'src' => 'ref1', '#' => 'name']); // /index.php?r=post/edit&id=100 assume the alias "@postEdit" is defined as "post/edit" echo Url::to(['@postEdit', 'id' => 100]); // the currently requested URL echo Url::to(); // /images/logo.gif echo Url::to('@web/images/logo.gif'); // images/logo.gif echo Url::to('images/logo.gif'); // http://www.example.com/images/logo.gif echo Url::to('@web/images/logo.gif', true); // https://www.example.com/images/logo.gif echo Url::to('@web/images/logo.gif', 'https');
稍做整理:有第二个参数且不是URL传递解析的内容就会得到绝对地址,也就是包含协议域名等部分的内容,另外能够引用配置参数是添加的别名
1): //获某网址 - 相对路径
$url = Url::to(['site/index']);
2): //获取网址(带参数) - 相对路径
$url = Url::to(['site/index', 'id' => 1]);
3): 获取当前路径 - 相对路径
$url = Url::to();
4): 获取url - 相对路径
$url = Url::to('@web/image/1.jpg');
说明:它将指定到你的某一个别名目录下@web
5): 获取url - 相对路径
$url = Url::to('image/1.jpg');
6): 获取url - 绝对路径(@mobileUrl 本身配置好的)
$url = Url::to('@mobileUrl/image/1.jpg', true);
7): //获取url -绝对路径(传输协议-https)
$url = Url::to('@mobileUrl/image/1.jpg', 'https');
8): //获取url -绝对路径(传输协议-http)
$url = Url::to('@mobileUrl/image/1.jpg', 'http');
(III)current() remember() previous()
current() 另外从2.0.3版本开始,你可使用 yii\helpers\Url::current() 来建立一个基于当前请求路由和 GET 参数的 URL。 你能够经过传递一个 $params 给这个方法来添加或者删除 GET 参数。 // /index.php?r=post/view&id=123&src=google echo Url::current(); // /index.php?r=post/view&id=123 echo Url::current(['src' => null]); // /index.php?r=post/view&id=100&src=google echo Url::current(['id' => 100]); 记住 URLs 有时,你须要记住一个 URL 并在后续的请求处理中使用它。 你能够用如下方式达到这个目的: // Remember current URL Url::remember(); // Remember URL specified. See Url::to() for argument format. Url::remember(['product/view', 'id' => 42]); // Remember URL specified with a name given Url::remember(['product/view', 'id' => 42], 'product'); 在后续的请求处理中,能够用以下方式得到记住的 URL: $url = Url::previous(); $productUrl = Url::previous('product'); 检查相对 URLs 你能够用以下代码检测一个 URL 是不是相对的(好比,包含主机信息部分)。 $isRelative = Url::isRelative('test/it');
5.关于render**系列的跳转
render是最长使用的一种跳转方法,必须填写的参数就是跳转去的页面,以后若是须要将参数传过去就能够把参数组成数组的形式传递去页面。然而有一个很明显的问题 ,这里不论你须要不须要都会带着layout中的header个footer一块儿。有疑问直接去看源码有时候是最快的解决方法。去看下源码:
public function render($view, $params = []) { $content = $this->getView()->render($view, $params, $this); return $this->renderContent($content); } //上面的函数最后仍是调用的下面的方法, public function renderContent($content) { //这里加载了布局方法 $layoutFile = $this->findLayoutFile($this->getView()); if ($layoutFile !== false) { return $this->getView()->renderFile($layoutFile, ['content' => $content], $this); } return $content; }
因此咱们能够直接本身调用if判断里面的内容去实现,可是对于这地方,YII仍是有作考虑的,能够看到一个函数:
public function renderPartial($view, $params = []) { return $this->getView()->render($view, $params, $this); }
这个就是实现了没有布局概念的跳转或者
public function renderFile($file, $params = []) { return $this->getView()->renderFile($file, $params, $this); }
另外有资料说redirect方法是控制器内跳转方法
public function redirect($url, $statusCode = 302, $checkAjax = true) { if (is_array($url) && isset($url[0])) { // ensure the route is absolute $url[0] = '/' . ltrim($url[0], '/'); } $url = Url::to($url); if (strpos($url, '/') === 0 && strpos($url, '//') !== 0) { $url = Yii::$app->getRequest()->getHostInfo() . $url; } if ($checkAjax) { if (Yii::$app->getRequest()->getIsAjax()) { if (Yii::$app->getRequest()->getHeaders()->get('X-Ie-Redirect-Compatibility') !== null && $statusCode === 302) { // Ajax 302 redirect in IE does not work. Change status code to 200. See https://github.com/yiisoft/yii2/issues/9670 $statusCode = 200; } if (Yii::$app->getRequest()->getIsPjax()) { $this->getHeaders()->set('X-Pjax-Url', $url); } else { $this->getHeaders()->set('X-Redirect', $url); } } else { $this->getHeaders()->set('Location', $url); } } else { $this->getHeaders()->set('Location', $url);//通常执行这里 } $this->setStatusCode($statusCode); return $this; }
从代码看,这是直接去对地址发起请求,将获得的结果进行处理。
再来整个梳理下:
(1)remder()
这是带模板的跳转,含带header和footer
(2) renderPartial()
(3)renderFile()
(2)(3)是不带模板的跳转,实际执行的代码同样,能够交替使用。
(4)redirect()
不支持参数POST传递。最后依然是调用header方法.只不过,自定义控制器里的redirect方法,是调用yii\web\Controller里边的redirect方法,而后调用yii\web\Response组件,而后在Response组件里边,调用yii\web\HeaderCollection类里边的get()方法,实现跳转的.或者执行http302重定向。利用这个方法,还能够实现外部服务器请求
另外能够参考YIIChina的部分教程和资料,例如:http://www.yiichina.com/tutorial/819