You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Phalcon中处理500和200错误并创建默认错误页面?

在Phalcon中处理500、200错误与自定义错误页面的最佳实践

结合你提供的service.php代码,我们可以通过以下步骤实现统一的错误处理和自定义错误页面:

一、扩展Dispatcher异常处理,覆盖500错误

在现有Dispatcher的dispatch:beforeException事件回调中,添加对500内部服务器错误的处理逻辑:

use \Phalcon\Mvc\Dispatcher as PhDispatcher;

$di->set(
    'dispatcher',
    function() use ($di) {
        $evManager = $di->getShared('eventsManager');

        $evManager->attach(
            "dispatch:beforeException",
            function($event, $dispatcher, $exception) use ($di) {
                switch ($exception->getCode()) {
                    case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                    case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                        $dispatcher->forward([
                            'namespace' => 'App\Controllers\Web',
                            'controller' => 'error',
                            'action'     => 'show404',
                        ]);
                        return false;
                    default:
                        // 处理所有未捕获的异常,作为500错误
                        $dispatcher->forward([
                            'namespace' => 'App\Controllers\Web',
                            'controller' => 'error',
                            'action'     => 'show500',
                        ]);
                        // 记录异常日志(需提前配置logger服务)
                        $logger = $di->getShared('logger');
                        $logger->error(
                            $exception->getMessage() . PHP_EOL . 
                            $exception->getTraceAsString()
                        );
                        return false;
                }
            }
        );
        $dispatcher = new PhDispatcher();
        $dispatcher->setEventsManager($evManager);
        return $dispatcher;
    },
    true
);

二、创建Error控制器,处理错误页面渲染

在app/controllers/Web/目录下创建ErrorController.php,包含404、500以及200响应的处理方法:

<?php
namespace App\Controllers\Web;

use Phalcon\Mvc\Controller;

class ErrorController extends Controller
{
    // 404页面处理
    public function show404Action()
    {
        $this->response->setStatusCode(404, 'Not Found');
        $this->view->pick('error/404');
    }

    // 500页面处理
    public function show500Action()
    {
        $this->response->setStatusCode(500, 'Internal Server Error');
        // 开发环境可传递异常详情,生产环境建议隐藏
        if ($this->config->app->debug) {
            $exception = $this->dispatcher->getParam('exception');
            $this->view->setVar('exception', $exception);
        }
        $this->view->pick('error/500');
    }

    // 统一200成功响应处理(可选,用于页面或接口统一格式)
    public function show200Action()
    {
        $this->response->setStatusCode(200, 'OK');
        // 根据需求渲染视图或返回JSON
        // $this->view->pick('success/200');
    }
}

三、创建自定义错误视图

在app/views/目录下创建error文件夹,分别添加404和500的视图文件:

404视图(app/views/error/404.volt)

<!DOCTYPE html>
<html>
<head>
    <title>404 - 页面未找到</title>
    <style>
        .error-wrap { text-align: center; padding: 60px 0; }
        h1 { font-size: 3.5em; color: #dc3545; margin: 0; }
        p { font-size: 1.2em; margin: 15px 0; }
        a { color: #0d6efd; text-decoration: none; }
    </style>
</head>
<body>
    <div class="error-wrap">
        <h1>404</h1>
        <p>抱歉,您访问的页面不存在或已被移除</p>
        <a href="/">返回首页</a>
    </div>
</body>
</html>

500视图(app/views/error/500.volt)

<!DOCTYPE html>
<html>
<head>
    <title>500 - 服务器内部错误</title>
    <style>
        .error-wrap { text-align: center; padding: 60px 0; }
        h1 { font-size: 3.5em; color: #dc3545; margin: 0; }
        p { font-size: 1.2em; margin: 15px 0; }
        a { color: #0d6efd; text-decoration: none; }
        .debug-info { text-align: left; max-width: 800px; margin: 30px auto; padding: 20px; background: #f8f9fa; border-radius: 5px; }
    </style>
</head>
<body>
    <div class="error-wrap">
        <h1>500</h1>
        <p>服务器内部出现错误,请稍后重试</p>
        <a href="/">返回首页</a>
        {% if exception %}
        <div class="debug-info">
            <h3>错误详情:</h3>
            <p><strong>消息:</strong>{{ exception.getMessage() }}</p>
            <p><strong>位置:</strong>{{ exception.getFile() }} 第 {{ exception.getLine() }} 行</p>
            <p><strong>调用栈:</strong></p>
            <pre>{{ exception.getTraceAsString() }}</pre>
        </div>
        {% endif %}
    </div>
</body>
</html>

四、全局PHP错误处理(可选)

为了捕获PHP致命错误、警告等非Dispatcher级别的错误,可在services.php中注册ErrorHandler:

use Phalcon\ErrorHandler;

$di->set('errorHandler', function() use ($di) {
    $errorHandler = new ErrorHandler();
    $errorHandler->setErrorTypes(E_ALL);
    
    $evManager = $di->getShared('eventsManager');
    $errorHandler->attach($evManager);
    
    // 注册全局错误处理
    $errorHandler->register();
    
    return $errorHandler;
}, true);

// 监听error事件,处理致命错误
$evManager->attach('error', function($event, $errorHandler, $exception) use ($di) {
    $logger = $di->getShared('logger');
    $logger->error($exception->getMessage() . PHP_EOL . $exception->getTraceAsString());
    
    if ($event->getType() === 'fatal') {
        ob_clean();
        $response = $di->getShared('response');
        $response->setStatusCode(500, 'Internal Server Error');
        $view = $di->getShared('view');
        $view->pick('error/500');
        echo $view->render();
        exit();
    }
});

五、200成功响应的统一处理(可选)

如果需要统一所有成功请求的响应格式(比如页面布局、API JSON结构),可以创建基础控制器:

<?php
namespace App\Controllers\Web;

use Phalcon\Mvc\Controller;

class BaseController extends Controller
{
    public function afterExecuteRoute($dispatcher)
    {
        // 统一设置200状态码
        $this->response->setStatusCode(200, 'OK');
        // 统一设置页面布局
        $this->view->setLayout('default');
    }
}

所有业务控制器继承BaseController即可自动应用统一规则。

内容的提问来源于stack exchange,提问作者Van Pham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:31:06