PHP MVC MySQL 错误处理

标签 php mysql model-view-controller exception

在 PHP MVC 应用程序中处理可能出现的 MySQL 错误的最常见/最佳实践是什么?最好将成功 bool 值从模型传递到 Controller 还是抛出异常? 假设我正在调用一个存储过程,我可能遇到的错误是数据库连接、用户没有权限、无效数据或随机 MySQL 错误,什么可能是最有效的处理方法。

例如: 方法一:

//UserController.php
private function get_user_info(){
    $user_info = $user_model->read_user_info(123);

    if($user_info[0]){
        //Do stuff with user data
    }else{
        //Check if db, permission, invalid data, or random MySQL error
    }
}

//UserModel.php
public function read_user_info($read_user_id){
    $stmt = $db->prepare("CALL read_user_info(?, ?)");

    $stmt->bindParam(1, $current_user_id);
    $stmt->bindParam(2, $read_user_id);

    if($stmt->execute()){
        $result_set = $stmt->fetchAll(PDO::FETCH_ASSOC);

        //Does the user have permission to read other user's info
        if($result_set["granted"]){
            return array(true, $result_set["user_info"]);
        }else{
            return array(false, "Permission error");
        }
    }else{
        return array(false, "MySQL error");
    }
}

方法2:

//UserController.php
private function get_user_info(){
    try{
        $user_info = $user_model->read_user_info(123);

        //Do stuff with user data
    }catch(ConnectionException $e){

    }catch(InvalidDataException $e){

    }catch(MySQLException $e){

    }
}

//UserModel.php
public function read_user_info($read_user_id){
    $stmt = $db->prepare("CALL read_user_info(?, ?)");

    $stmt->bindParam(1, $current_user_id);
    $stmt->bindParam(2, $read_user_id);

    if($stmt->execute()){
        $result_set = $stmt->fetchAll(PDO::FETCH_ASSOC);

        //Does the user have permission to read other user's info
        if($result_set["granted"]){
            return $result_set["user_info"];
        }else{
           throw new PermissionException();
        }
    }else{
        throw new MySQLException();
    }
}

最佳答案

Would it be best to pass an success boolean from the model to controller or to throw exceptions?

整个错误处理最好在模型中完成,因为它是整个 MVC 应用程序概念中“可重用”代码的正确位置。

what could be the most efficient / effective method for handling.

我说的是方法1。首先, Controller 仅接收 user_info 变量,并在此事件上应用自定义逻辑,特别是在不捕获各种 Exception 和处理的情况下(恕我直言,这应该集中在模型)。

无论如何,设置自定义错误处理程序可能会变得非常有用 - 集中方法、错误显示、日志管理等)。我使用的示例 Error 类:

public static $error_types = array(
    E_ERROR => 'E_ERROR',
    E_WARNING => 'E_WARNING',
    E_PARSE => 'E_PARSE',
    E_NOTICE => 'E_NOTICE',
    E_CORE_ERROR => 'E_CORE_ERROR',
    E_CORE_WARNING => 'E_CORE_WARNING',
    E_COMPILE_ERROR => 'E_COMPILE_ERROR',
    E_COMPILE_WARNING => 'E_COMPILE_WARNING',
    E_USER_ERROR => 'E_USER_ERROR',
    E_USER_WARNING => 'E_USER_WARNING',
    E_USER_NOTICE => 'E_USER_NOTICE',
    E_STRICT => 'E_STRICT',
    E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
    E_DEPRECATED => 'E_DEPRECATED',
    E_USER_DEPRECATED => 'E_USER_DEPRECATED'
);

public static $throwables = array();

public static function set_throwable_handlers()
{
    error_reporting(E_ALL);
    ini_set('display_errors', FALSE);
    ini_set('log_errors', TRUE);
    ini_set('error_log', APP_DIR.DIR_SEP.'system'.DIR_SEP.'logs'.DIR_SEP.'error.log');

    set_error_handler(array('Error', 'error_handler'));
    set_exception_handler(array('Error', 'exception_handler'));

    register_shutdown_function(array('Error', 'shutdown_handler'));
}

public static function set_throwable($error_number, $error_text, $error_file, $error_line)
{
    self::$throwables[$error_number][] = array('type' => self::$error_types[$error_number], 'text' => $error_text, 'file' => $error_file, 'line' => $error_line);
}

public static function exception_handler(Exception $exception)
{
    self::set_throwable($exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine());
}

public static function error_handler($error_number = '', $error_text = '', $error_file = '', $error_line = '')
{
    self::set_throwable($error_number, $error_text, $error_file, $error_line);
}

public static function shutdown_handler()
{
    $error = error_get_last();

    if ($error !== NULL)
    {   
        self::set_throwable($error['type'], $error['message'], $error['file'], $error['line']);

        View::display();
    }
}

public static function throw_error($error_text, $error_number = E_USER_NOTICE)
{
    trigger_error($error_text, $error_number);

    View::display();

    exit;
}

关于PHP MVC MySQL 错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19329344/

相关文章:

mysql - SQL 内连接性能问题

javascript - AngularJS JSON 对象在 View 中可访问,但在 Controller 中不可访问

javascript - 如何在初始页面加载时禁用 Backbone.js 路由

php - 在查询之前检查是否有重复的电子邮件

php - 从 div 中的选择中删除/隐藏选项

mysql - 尝试将 Access 插入查询转换为 MySQL 查询

javascript - 为什么我收到 UnhandledPromiseRejectionWarning : Unhandled promise rejection?

php - 我如何获得这个基于网络的文字处理器?

php - 如何仅显示自日期以来和截止日期的数据

java - GUI中的异常和显示错误消息