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
Mysql_Fetch_Array Returns Duplicate Data
Parse Math Operations with PHP
Storing Time Information: Timezone Required
Populate Select Drop Down from a Database Table
PHP Include File in Webroot from File Outside Webroot
Printing Content of a Xml File Using Xml Dom
How to Enable Put Requests in Azure
Multi Checkbox Fields in Woocommerce Backend
Select MySQL Rows But Rows into Columns and Column into Rows
How to Get Value from Form Without Submitting It
PHP Using Declare? What Is a Tick
Creating a Folder When I Run File_Put_Contents()
PHP Float with 2 Decimal Places: .00
Simpler Way to Check If Variable Is Not Equal to Multiple String Values
Php: How to Check If a Date Is Today, Yesterday or Tomorrow