phalconphalcon-routing

Redirecting to 404 route in PhalconPHP results in Blank Page


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.


Solution

  • 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();
    }