在日常的web开发中,跳转是一个很常见的操作,成功了要跳转,错误了要跳转,满足某某条件也要跳转,symfony作为一款成熟的开发框架对跳转的处理也是非常多样的。
一. 关于跳转
虽说多样,但万变不离其宗,一般的跳转分为两种,forward(转发)和redirect(重定向),两种方法虽然目的都是为了进行跳转但是本质上还是有很大差别的。
所谓forward,是一个action将当前的请求交给另外一个action处理,这个过程是在同一个http请求中完成的,整个过程不涉及客户端,url地址也不会发生改变。
示例1
public function executeActionA($request)
{
// 一些处理
// to ActionB: 剩下的就交给你了
$this->forward('default', 'actionb');
}
public function executeActionB($request)
{
// to ActionA: 交给我你就放心吧
// 又一些处理
}
示例一中,ActionA将处理工作交给的ActionB,其实其效果是和下例一样的。
示例2
public function executeActionC($request)
{
// 一些处理
// 又一些处理
// ps : 我是全能,ActionA和ActionB能做的我自己就能做
}
上面这两个例子就如同我们雇佣一个程序员一个美工或者雇佣一个懂美工的程序员一样,我们将事件处理过程分开总是有各种各样的原因,比如为了逻辑清晰,代码重用等等等等,所以在很多情况下我们就需要使用forward。
说完forward我们再来说redirect,其实我觉得redirect才能够叫做真正的跳转,很多时候我觉得forward就象调用函数。一 个真正的redirect涉及了两次http请求,浏览器发送了一个http请求之后,服务端根据业务需要进行跳转,这样服务端会向浏览器返回一个跳转信 息,这个跳转信息可能是一个重定向的http header,也可能是一段带有跳转代码的html或者javascript,浏览器接到请求根据跳转信息进行第二次http 请求,这个第二次请求不同于forward的第二个Action,这个请求可以在程序内,也可以在程序外,比如说跳到google, 而用forward就象蹲监狱,再怎么跳也就是换换牢房,想出去是不可能了,除非你是Michael Scofield。
示例3
public function executeActionA($request)
{
// 我要换牢房
$this->redirect('fox/room');
}
public function executeActionB($request)
{
// 我要换去Sucre的牢房拆马桶
$this->redirect("fox/room?user='Fernando Sucre'");
}
public function executeActionC($request)
{
// 和哥哥越狱到谷歌去
$this->redirect('http://g.cn/?with_my_brother=true');
}
这里扯的有点远,其实我觉得在看我文章的朋友其实已经有一定的symfony基础的,所以不需要细细的去讲,只要给大家一些提示就可以。 forward和redirect还有很关键的一点区别,就是forward进行转发之后原来的请求参数不会变,这里的请求参数指post, get, cookie什么什么什么的, 而redirect就需要你通过url将你需要的参数再传过去, symfony中貌似有http_build_query()这么一个函数.
示例4
public function executeActionA($request)
{
// 所有和我从Fox River跑出来的朋友一起去巴拿马
$this->redirect('panama.com?'.http_build_query($request->getPostParameters()));
}
二. symfony中的跳转
关于forward和redirect就介绍到这里,下面来介绍symfony中的跳转方法。
function forward($module, $action)
最基本的转发动作,参数是模块名和动作名。
示例5,新建立模块的Index方法都是这样的。
public function executeIndex(sfWebRequest $request)
{
// 将默认动作转发到默认模块
$this->forward('default', 'index');
}
function forward404($message = null)
forward404动作其实和throw new sfError404Exception的效果是一样的, 在symfony中可以通过设置404动作来控制404的输出,这样实际上就是一个转发到404错误处理动作的跳转, 返回404异常在程序中是很常见的,比如参数错误,数据错误等等等等等等,我们都可以直接抛出404异常。
示例6
public function executeActionA($request)
{
$id = (int) $request->getParameter('id');
if ($id < 1) {
$this->forward404();
}
$product = ProductPeer::retrieveByPk($id);
if (!is_object($product)) {
$this->forward404();
}
//我们将对象注册到模板中去,其实和$this->product=$product是一样的
$this->setVar('product', $product);
}
function forwardIf($condition, $module, $action)
当$condition为”真”的时候转发到$module/$action
示例7
public function executeCreate($request)
{
$product = new Product;
$product->setName('产品1');
// 创建产品,成功则跳转到列表,创建失败则抛出404
$this->forwardIf($product, 'product', 'list');
$this->forward404();
}
function forwardUnless($condition, $module, $action)
当$condition为”假”的时候转发到$module/$action
示例8
public function executeAction($request)
{
$product = ProductPeer::retrieveByPk($this->getParameter('id'));
$this->forward($product, 'default', 'error404');
}
function forward404If($condition, $message = null)
当$condition为“真“的时候抛出404异常
示例9
public function executeShow($request)
{
$id = intval($request->getParameter('id'));
// 如果id小于0抛出异常
$this->forward404If($id<0, 'parameter error');
$product = ProductPeer::retrieveByPk($id);
// 如果产品不存在抛出异常
$this->forward404If(!$product, 'product not exists');
$this->object = $product;
}
function forward404Unless($condition, $message = null)
当$condition为“假“的时候抛出404异常, 实际应用中这个方法比forward404If更方便
示例10
public function executeShow($request)
{
$id = intval($request->getParameter('id'));
// 如果id小于0抛出异常
$this->forward404If($id<0, 'parameter error');
$product = ProductPeer::retrieveByPk($id);
// 如果产品不存在抛出异常
$this->forward404Unless($product, 'product not exists');
$this->object = $product;
}
function redirect($url, $statusCode = 302)
跳转到$url,返回http状态码,$url可以是内部url也可以是外部url.
示例11
public function executeActionA($request)
{
$this->redirect('g.cn');
}
public function executeActionB($request)
{
$this->redirect('default/index?action=b');
}
function redirect404()
跳转到404动作,404处理动作可以通过settings.yml进行设置, 这个动作是不用给参数的,symfony会自动调用系统设置。
function redirectIf($condition, $url, $statusCode = 302)
如果$condition为“真”则跳转到$url
示例12
public function executeCreate($request)
{
$product = new Product;
$product->setName('产品2');
//创建成功进入编辑页面
$this->redirectIf($product->save(), 'product/update?id='.$product->getId());
//创建失败加载Error模板
return sfView::ERROR;
}
function redirectUnless($condition, $url, $statusCode = 302)
如果$condition为“假”则跳转到$url, 参考forwardUnless
转载于:https://blog.51cto.com/leexiaobo/944713