Pragmatism in the real world

The Redirector action helper

Following on from the discussion on the FlashMessenger action helper, I thought I’d also cover another supplied helper: Redirector.

Redirector does what it says on the tin and redirects the user to another page. I mostly use this when coming back from filling a form in, so that the user is then redirected to another page. In admin systems, this is usually a list page. On front end websites, this is usually a thank you page. Though for log-in forms, I tend to try and return the user to where they were going!

It’s used in a controller action method like this:
$urlOptions = array('controller'=>'index', 'action'=>'index');
$this->_helper->redirector->gotoRoute($urlOptions);

gotoRoute() takes the same set of parameters are the url() view helper which is not a surprise as they both proxy through to the Front Controller’s router object. It’s handy though as one you know one, you know the other :)

If you are using the default route, then you can use gotoSimple(). For example to redirect to the news controller’s list action, you would do:
$this->_helper->redirector->gotoSimple('list', 'news');

The gotoSimple() method signature is:
gotoSimple($action, $controller = null, $module = null, array $params = array());
As you can see, it provides defaults for the controller and module and params parameters so you only need to set them if you need to. This works well for admin system as I tend to be redirecting within the same controller (from the edit or delete action to index, usually).

You can also use the Redirector with an absolute URL, by using the gotoUrl() method:
$url = 'http://www.akrabat.com';
$this->_helper->redirector->gotoUrl($url);

I tend to use this one much less frequently – so infrequently, that I can’t think of a use-case off the top of my head :)

By default, Redirector sets a 302 status code, however you can also set a 301 if you want to:

$this->_helpers->redirector->setCode(301);

There are a few other options that can be set like setExit() and setUseAbsoluteUri(), but to be honest, I don’t think I’ve ever used them!

I find that I use Redirector fairly frequently as its gotoRoute() uses the same parameters as url() which makes it easy to remember how to use it. Like url(), it also benefits from remembering which route was used to get you to the current page and reuses that when creating the next one which is handy.

7 thoughts on “The Redirector action helper

  1. Internally, the Redirector action helper calls exit() when done so as to complete the request as quickly as possible. setExit() allows you to override that behavior if desired; in fact, Zend_Test disables that behavior so as to allow execution to return to the test case!

    As for setUseAbsoluteUri(), this was put in place to address HTTP purists. By default, the Redirector builds only the path segment of a URL (and potentially the query string); technically speaking, however, you should always build fully qualified URLs (i.e., include the schema, host, and optionally port) for full compatibility across HTTP clients — which is what this flag allows. That said, I have yet to run across a modern HTTP client that will not resolve URL paths to the appropriate schema and host for you.

    Finally, I'll note that _redirect() actually proxies to the Redirector's gotoUrl() method — so even if you're not using the Redirector action helper directly, you may have used it indirectly previously.

  2. Hi Matthew,

    Since writing this post, I happened to be unit testing a controller action that used redirector and discovered that Zend_Test_Controller_TestCase uses setExit() as it caused no end of trouble that I still need to document here :)

    Regards,

    Rob…

  3. Rob — the rule of thumb is: always return when you redirect or forward. :)

    The ViewRenderer and Layout are smart enough to recognize that a redirect is happening, and will not operate. However, not all plugins are similarly aware — and if you do not return immediately, you may have other code that executes within your action that you don't want to run.

    These are all seen VERY clearly when you unit test your controllers, which I suspect you've now discovered. :)

  4. I have a problem redirecting when using http://localhost/~cdndev/test1/public (index/index redirects to auth/index) but it works fine when I use an alias in apache (http://test1.local).

    I'm getting 404: "The requested URL /home/cdndev/public_html/test1/public/index.php was not found on this server."

    The location bar shows "http://localhost/~cdndev/test1/public/auth" after I typed in "http://localhost/~cdndev/test1/public" so obviously it did hit the site and tries to redirect and then fails.

    I'm baffled as to why it works one way (using an alias) but not the other (~/public_hmtl).

    Can you please explain?

    Thanks,
    Jamie

    By the way, loved the book (bought it through MEAP) and am now finally going to get to use it for a real project.

  5. Hi, i am learning zf and i got problem with one of your scripts and it's all about redirector(). Here is a code in one of my helpers but redirector doesn't work. I tried also init function and it give me nothing more.

    Errors:
    Notice: Undefined property: Application_Helper_Login::$_helper
    Fatal error: Call to a member function redirector() on a non-object

    public function preDispatch()
    {
    $view = $this->getActionController()->view;
    $form = new Form_LoginForm();

    $request = $this->getActionController()->getRequest();
    if($request->isPost() && $request->getPost('send'))
    {
    if($form->isValid($request->getPost()))
    {
    if($this->_process($form->getValues()))
    {
    // Success: Redirect to the home page
    $this->_helper->redirector('index','index');
    }
    }
    }
    $view->signupForm = $form;
    }

Comments are closed.