1

I have setup a router, and in it, defined a route for 404s:

<?php

use Phalcon\Mvc\Router;
$router = new Router(FALSE);
$router->removeExtraSlashes(true);

$route = $router->add('/', ['controller' => 'index', 'action' => 'index']);
$route->setName("index");

// other routes defined here...

$router->notFound([
  "controller" => "index",
  "action" => "route404"
]);

?>

My IndexController:

<?php

class IndexController extends ControllerBase
{

    public function indexAction()
    {
    // code removd for berevity 
    }

    public function route404Action() {
      // no code here, I just need to show the view.
    }

}
?>

And I have a view @ /app/views/index/route404.phtml that just has a bit of HTML in it, I even tried making it a .volt file, no luck.

When I go to a page that doesn't match any routes, it works fine. But, if I try to redirect to it, I just get a blank page. For example, in one of my controllers I have this:

if (!$category) {
  // show 404

  //Tried this next line to test, and it indeed does what you'd expect, I see "Not Found". 
  // echo "Not Found"; exit;  

  $response = new \Phalcon\Http\Response();
      $response->redirect([
    "for" => "index", 
    "controller" => "index", 
    "action" => "route404"]
  );

  return; // i return here so it won't run the code after this if statement.
}

Any ideas? The page is completely blank (nothing in source) and there are no errors in my apache logs.

Thom Porter
  • 2,604
  • 2
  • 19
  • 23

1 Answers1

4

Try returning the response object, not just a blank return. Example:

return $this->response->redirect(...);

However I would recommend to use Forward from dispatcher to show 404 pages. This way user will stay on same url and browser will receive the correct status code (404). Also it's SEO friendly this way :)

Example:

if ($somethingFailed) {
    return $this->dispatcher->forward(['controller' => 'index', 'action' => 'error404']);
}  

// Controller method
function error404Action()
{   
    $this->response->setStatusCode(404, "Not Found"); 
    $this->view->pick(['_layouts/error-404']);
    $this->response->send();
}    
Nikolay Mihaylov
  • 3,868
  • 8
  • 27
  • 32
  • Excellent answer! Your recommendation was exactly what I was looking for! I ended up adding a `notFound()` method to the ControllerBase just to make it easier to use from multiple controllers/locations. Thanks! =) – Thom Porter Apr 01 '16 at 02:28
  • Glad i helped, with forward you hit two rabbits with one stone: little more usability for the user and making those seo experts happy :) – Nikolay Mihaylov Apr 01 '16 at 06:12