21

当控制器/动作不存在时,如何在 Phalcon 中设置 404 页面显示?

4

4 回答 4

47

您可以设置调度程序为您执行此操作。

当您引导您的应用程序时,您可以这样做($di是您的 DI 工厂):

use \Phalcon\Mvc\Dispatcher as PhDispatcher;

$di->set(
    'dispatcher',
    function() use ($di) {

        $evManager = $di->getShared('eventsManager');

        $evManager->attach(
            "dispatch:beforeException",
            function($event, $dispatcher, $exception)
            {
                switch ($exception->getCode()) {
                    case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                    case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                        $dispatcher->forward(
                            array(
                                'controller' => 'error',
                                'action'     => 'show404',
                            )
                        );
                        return false;
                }
            }
        );
        $dispatcher = new PhDispatcher();
        $dispatcher->setEventsManager($evManager);
        return $dispatcher;
    },
    true
);

创建一个ErrorController

<?php

/**
 * ErrorController 
 */
class ErrorController extends \Phalcon\Mvc\Controller
{
    public function show404Action()
    {
        $this->response->setStatusCode(404, 'Not Found');
        $this->view->pick('404/404');
    }
}

和 404 视图 ( /views/404/404.volt)

<div align="center" id="fourohfour">
    <div class="sub-content">
        <strong>ERROR 404</strong>
        <br />
        <br />
        You have tried to access a page which does not exist or has been moved.
        <br />
        <br />
        Please click the links at the top navigation bar to 
        navigate to other parts of the site, or
        if you wish to contact us, there is information in the About page.
        <br />
        <br />
        [ERROR]
    </div>
</div>
于 2012-12-28T14:47:32.797 回答
13

您可以使用路由来处理 404 not found 页面:

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

参考:http ://docs.phalconphp.com/en/latest/reference/routing.html#not-found-paths

于 2014-07-09T08:09:51.410 回答
5

Dimopoulos 提出的解决方案不起作用。它产生一个循环条件。

Phalcon 路由器组件有一个默认行为,它提供了一个非常简单的路由,它总是需要一个匹配以下模式的 URI:/:controller/:action/:params。这会导致很多问题,因为当服务器接收到一个与任何定义的路由都不匹配的 URL 请求时,Phalcon 将搜索一个不存在的控制器。

因此,首先,您必须禁用此行为。这可以FALSE在 Router 实例创建期间传递,如下所示:

$router = Phalcon\Mvc\Router(FALSE);

此时您可以使用@Nguyễn Trọng Bằng 提出的解决方案。

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

重要的是要注意,如果您使用命名空间,调度程序将无法找到控制器,除非您指定它,就像我在上面所做的那样。

这不仅是最简单的解决方案,而且是唯一有效的解决方案。

于 2014-07-14T14:51:31.393 回答
4

您还可以使用在 errorController 中设置标题

class ErrorController extends ControllerBase
{
     public function error404Action()
    {
        $this->response->setHeader('HTTP/1.0 404','Not Found');
        // $this->response->setHeader(404, 'Not Found'); <- did not work
    }
}

而之前,在控制器中,发生错误的地方,您可以转发到这个错误控制器。

class IndexController extends ControllerBase
{
    public function indexAction()
    {
        $id = (int)$this->getId($param);
        if ($id > 0) {

           // do you stuff
        } else {
           $this->dispatcher->forward(array(
               'controller' => 'error', 'action' =>   'error404')
           );
        }
    }
}

这是一种快速而肮脏(?)的方式,并且很好,如果您从数据库中获取内容并且想要抛出错误,如果没有找到任何东西。

于 2013-09-12T20:02:12.017 回答