Differencebetween Redirect and Forward in Zend Framework

What is the difference between redirect and forward in Zend framework

_forward() just forwards everything to another controller action, while _redirect() sends a header, meaning you create a new HTTP Request and go through the entire dispatch process with it.

For instance, if you call up http://example.com/foo/bar you'd call the foo controller and bar action. If you forward inside the bar action to the baz action, e.g. within the very same request, the browser would still be on the same URL, while when doing a redirect, ZF would instruct the browser to load http://example.com/foo/baz.

Essentially, _forward() does

$request->setActionName($action)
->setDispatched(false);

while _redirect() does

$this->_helper->redirector->gotoUrl($url, $options);

I usually do redirects when I want to prevent reload a page resulting in reposting form data.

See these:

  • Zend Framework, what $this->_forward is doing
  • http://osdir.com/ml/php.zend.framework.mvc/2007-09/msg00038.html
  • http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Controller/Action/Helper/Redirector.php

Which cases should be used _redirect() or _forward() in Zend Framework

both are totally different things _forward is internal redirection of zf , i.e practically user browser even dont know about this redirection , but inside zf all the hooks after predispatch gets invoked . Whereas in _redirect case user browser takes control of redirection and make second request hence everthing inside zf gets invoked once age (bootstrap , routing etc) .

clearely _forward is less resource intensive then _redirect but if you need the code inside bootstrap to be called (in case you have made changes in config and want it to reload) then you should do _redirect .

Is it possible to forward data to another controller/action in Zend 2?

There are two options to "forward". Understand php is as server side language a processor to grab an incoming request and return a response.

That said, the first "forward" uses in-framework forwarding. This means there is only one request and one response. Internally the framework calls one controller action and then another one. Zend Framework calls this method forward.

The second "forward" is a real redirect, where the first response contains a Location header and the 302 http status code. This results in a second request and consecutively in a second response. Zend Framework calls this method redirect.

So with above, the forward you talk about in your question does not involve any sessions or route match parameters, since the second call to an action is within the same php process, so all variables are already known.

Forward example

An example to forward is to use the forward controller plugin:

class MyController
{
public function myAction()
{
return $this->forward()->dispatch('MyModule\Controller\Other', array(
'action' => 'other',
'foo' => 'bar',
'baz' => new Bat()
));
}
}

To access:

class OtherController {
public function otherAction()
{
$foo = $this->params()->fromRoute('foo');
}
}

As you might note, it is possible to add additional parameters to the forward call including real objects.

Redirect example

One option is to use the route parameters, so you capture data in the url you send back. Because you say you don't want that, you have to use a session for that:

use Zend\Session\Container;

class MyController
{
public function myAction()
{
$session = new Container('MyContainer');
$session->foo = 'bar';
$session->baz = 'bat';

return $this->redirect()->toRoute('my/other/route');
}
}

Zend redirecting What's the difference between these 2 ways

The Redirector helper allows you to
use a redirector object to fulfill
your application's needs for
redirecting to a new URL. It provides
numerous benefits over the _redirect()
method, such as being able to
preconfigure sitewide behavior into
the redirector object or using the
built in gotoSimple($action,
$controller, $module, $params)
interface similar to that of
Zend_Controller_Action::_forward().

The main differece compared to setController() and setAction() in the request object is that you'll change the url (302 redirection), not just the action. Also, as you can see, the _redirect() method is a shortcut to the redirecotor helper which provide more functionalities than just redirect. You can see those here: http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#Redirector

The $this->_forward() method do the same as setController() and setAction() and is a method of Zend_Controller_Action class:

final protected function _forward($action, $controller = null, $module = null, array $params = null)
{
$request = $this->getRequest();

if (null !== $params) {
$request->setParams($params);
}

if (null !== $controller) {
$request->setControllerName($controller);

// Module should only be reset if controller has been specified
if (null !== $module) {
$request->setModuleName($module);
}
}

$request->setActionName($action)
->setDispatched(false);
}

If you're on Zend_Controller_Action you can use this method above, but if you're on Zend_Controller_Plugin for example you need to use the request object directly.

When you submit a form for example, it's a good pratice redirect instead of forward to prevent the form from being submitted twice if the user refresh the page.

For more information about this proccess:

http://framework.zend.com/manual/en/zend.controller.dispatcher.html

http://devzone.zend.com/article/11978

Zend Framework, what $this-_forward is doing

_forward is an internal redirect. Where as _redirect sends a header that tells the client's browser to go to some other URL, _forward tells the Dispatcher to internally redirect the request somewhere else.

If you consider the normal dispatch order of:

 preDispatch()
someAction()
postDispatch()

Calling _forward at any point in that progression will cause the following steps to not be executed. So if you call _forward in preDispatch(), someAction() will not be called and so on. If you _forward() in someAction() and you are using the viewRenderer action helper to render your views (you are letting the framework choose what view script to render), then no view script will be rendered in someAction().

When the request is forwarded to the new Controller / Module the entire dispatch process will be repeated there.

You can find out what action is being dispatched by using:

 $action = $this->getRequest()->getParam('action');

$action will be the url form of the action so if the method is name 'someKindOfAction', $action will contain 'some-kind-of'. You can do this as well for controllers and modules.

Using Zend framework to redirect/forward (similar to 301 status) old URLs to new controllers/actions

I'll start off by recommending using your apache config to place the rewrites if possible. It's much faster than both using .htaccess and your Zend Framework application.

I'll also say that you do want to use 301 redirects as they are the best for search engines when your content has been moved permanently.

If you want to use your Zend Framework application to do this and if you have a bunch of URLs that may have different structures, the best place is in the default error controller as a 'last ditch effort'. The reason for this is that if you have an url /myoldurl that doesn't exist now (but is on your redirect list) and you implement it in the future as it's own controller/module - your controller will automatically take over.

Inside errorAction() there is a switch that decides if your error is a 404 or a 500.

Inside the 404 block you can add code to do a redirect. This is not complete code, look it over and insert missing pieces of data as needed.

// [code omitted]
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
// this is the original request string ie: /myoldurl
$pathinfo = $this->_request->getPathInfo();

// decide if pathinfo is in your redirect list
if ($pathinfo is in some list of old urls) {
// and get $newurl from your list
$newurl = something from a list of new urls;

// set redirect code to 301 instead of default 302
$this->_helper->redirector->setCode(301);
$this->_redirect($newurl);
}
// 404 error -- controller or action not found
$this->getResponse()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
//[...]

Zend Framework forward request with post http method

Yes this is possible, Try using following:

$this->_request->setPost(array('param_name' => $paramValue));
$this->_forward('actionName', 'controller', 'module');


Related Topics



Leave a reply



Submit