PHP错误码怎么统一管理

wen PHP项目 1

本文目录导读:

PHP错误码怎么统一管理

  1. 常量定义法(最基础)
  2. 异常类封装法(推荐)
  3. 配置文件方式(适合多环境)
  4. 全局异常处理器
  5. 完整示例:统一响应格式
  6. 错误码管理工具类
  7. 最佳实践建议:

在PHP中统一管理错误码,我建议采用以下几种成熟方案:

常量定义法(最基础)

<?php
// error_codes.php
class ErrorCode {
    // 通用错误码 (1xxx)
    const SUCCESS = 0;
    const PARAM_ERROR = 1001;
    const AUTH_FAILED = 1002;
    const NOT_FOUND = 1003;
    const FORBIDDEN = 1004;
    const SYSTEM_ERROR = 1005;
    // 业务错误码 (2xxx)
    const USER_NOT_EXIST = 2001;
    const USER_PASSWORD_ERROR = 2002;
    const USER_DUPLICATE = 2003;
    // 其他平台错误码 (3xxx)
    const SMS_SEND_FAILED = 3001;
    const EMAIL_SEND_FAILED = 3002;
    // 错误消息映射
    public static $messages = [
        self::SUCCESS => '操作成功',
        self::PARAM_ERROR => '参数错误',
        self::AUTH_FAILED => '认证失败',
        self::NOT_FOUND => '资源不存在',
        self::FORBIDDEN => '没有权限',
        self::SYSTEM_ERROR => '系统错误',
        self::USER_NOT_EXIST => '用户不存在',
        self::USER_PASSWORD_ERROR => '密码错误',
        self::USER_DUPLICATE => '用户已存在',
        self::SMS_SEND_FAILED => '短信发送失败',
        self::EMAIL_SEND_FAILED => '邮件发送失败',
    ];
    // 获取错误消息
    public static function getMessage($code) {
        return self::$messages[$code] ?? '未知错误';
    }
}
?>

异常类封装法(推荐)

<?php
// exceptions/BusinessException.php
class BusinessException extends Exception {
    private $errorCode;
    private $errorData;
    public function __construct($errorCode, $message = '', $errorData = [], Exception $previous = null) {
        $this->errorCode = $errorCode;
        $this->errorData = $errorData;
        // 如果没传message,自动从配置获取
        if (empty($message)) {
            $message = ErrorCode::getMessage($errorCode);
        }
        parent::__construct($message, $errorCode, $previous);
    }
    public function getErrorCode() { return $this->errorCode; }
    public function getErrorData() { return $this->errorData; }
}
// 子类扩展
class UserException extends BusinessException {
    public static function notFound() {
        return new self(ErrorCode::USER_NOT_EXIST);
    }
    public static function passwordError() {
        return new self(ErrorCode::USER_PASSWORD_ERROR);
    }
}
?>

配置文件方式(适合多环境)

<?php
// config/error_codes.php
return [
    'LOCAL' => [
        'success' => 0,
        'param_error' => 1001,
        'auth_failed' => 1002,
    ],
    'PRODUCTION' => [
        'success' => 0,
        'param_error' => 40001,
        'auth_failed' => 40002,
    ],
];
// ErrorCodeService.php
class ErrorCodeService {
    private $errorCodes;
    public function __construct($env = 'LOCAL') {
        $this->errorCodes = require 'config/error_codes.php';
        $this->errorCodes = $this->errorCodes[$env];
    }
    public function getCode($key) {
        return $this->errorCodes[$key] ?? 99999;
    }
}
?>

全局异常处理器

<?php
// global_exception_handler.php
class GlobalExceptionHandler {
    public static function register() {
        set_exception_handler([self::class, 'handleException']);
        set_error_handler([self::class, 'handleError']);
        register_shutdown_function([self::class, 'handleFatalError']);
    }
    public static function handleException($e) {
        $response = [
            'code' => $e instanceof BusinessException ? $e->getErrorCode() : 500,
            'message' => $e->getMessage(),
            'data' => $e instanceof BusinessException ? $e->getErrorData() : null
        ];
        // 记录日志
        Log::error('系统异常', [
            'message' => $e->getMessage(),
            'file' => $e->getFile(),
            'line' => $e->getLine(),
            'code' => $e->getCode()
        ]);
        // 根据环境决定是否显示详细错误
        if (ENV !== 'development') {
            $response['message'] = '系统错误,请稍后重试';
        }
        echo json_encode($response);
        exit;
    }
    public static function handleError($errno, $errstr, $errfile, $errline) {
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
    public static function handleFatalError() {
        $error = error_get_last();
        if ($error !== null) {
            $e = new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']);
            self::handleException($e);
        }
    }
}
// 注册全局异常处理
GlobalExceptionHandler::register();
?>

完整示例:统一响应格式

<?php
// ApiResponse.php
class ApiResponse {
    private $code;
    private $message;
    private $data;
    public function __construct($code = 0, $data = [], $message = '') {
        $this->code = $code;
        $this->data = $data;
        $this->message = $message ?: ErrorCode::getMessage($code);
    }
    public static function success($data = []) {
        return new self(ErrorCode::SUCCESS, $data);
    }
    public static function error($code, $message = '', $data = []) {
        return new self($code, $data, $message);
    }
    public function toJson() {
        // 记录API日志
        Log::info('API响应', [
            'code' => $this->code,
            'message' => $this->message,
            'data' => $this->data
        ]);
        return json_encode([
            'code' => $this->code,
            'message' => $this->message,
            'data' => $this->data
        ]);
    }
}
// 使用示例
try {
    $user = $userService->getUser($userId);
    echo ApiResponse::success(['user' => $user])->toJson();
} catch (BusinessException $e) {
    echo ApiResponse::error($e->getErrorCode(), $e->getMessage(), $e->getErrorData())->toJson();
} catch (Exception $e) {
    // 记录严重错误
    Log::error('未捕获异常', ['exception' => $e]);
    echo ApiResponse::error(ErrorCode::SYSTEM_ERROR)->toJson();
}
?>

错误码管理工具类

<?php
// ErrorCodeManager.php
class ErrorCodeManager {
    private static $instance = null;
    private $errorCodes = [];
    private $configPath = 'config/error_codes.php';
    private function __construct() {
        $this->loadErrorCodes();
    }
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    private function loadErrorCodes() {
        $this->errorCodes = require $this->configPath;
    }
    public function getMessage($code) {
        return $this->errorCodes['messages'][$code] ?? '未知错误';
    }
    public function getCode($key) {
        return $this->errorCodes['codes'][$key] ?? 99999;
    }
    public static function translate($code) {
        return self::getInstance()->getMessage($code);
    }
}
// 静态调用封装
if (!function_exists('error_message')) {
    function error_message($code) {
        return ErrorCodeManager::translate($code);
    }
}
if (!function_exists('error_code')) {
    function error_code($key) {
        return ErrorCodeManager::getInstance()->getCode($key);
    }
}
?>

最佳实践建议:

  1. 统一规范:错误码按模块分段,如1xxx通用、2xxx用户、3xxx订单等
  2. 文档化:维护错误码文档,包含含义和处理建议
  3. 日志记录:记录错误发生时的上下文
  4. 多语言支持:错误消息支持多语言
  5. 监控报警:对重要错误码设置监控

这些方案可以根据你的项目复杂度选择使用,中小型项目推荐使用异常类封装法,大型项目可以配置文件和异常类结合使用。

抱歉,评论功能暂时关闭!