Codeigniter 4 - MySQL 重复条目异常不起作用

问题描述 投票:0回答:1

我正在使用 Codeigniter v4.4.5 并努力捕获 MySQL 重复条目异常。如果有任何重复的值,那么我想在我的控制器中处理,以便我可以将相关消息发送回用户。但是,当出现重复条目错误时,Codeigniter 会记录异常,但不会将该异常发送回控制器。我进一步调查,可以看到异常首先在 CodeIgniter\Database\MySQLi\Connection.php 中引发(代码如下)

protected function execute(string $sql)
    {
        while ($this->connID->more_results()) {
            $this->connID->next_result();
            if ($res = $this->connID->store_result()) {
                $res->free();
            }
        }

        try {
            return $this->connID->query($this->prepQuery($sql), $this->resultMode);
        } catch (mysqli_sql_exception $e) {
            log_message('error', (string) $e);

            if ($this->DBDebug) {
                throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
            }
        }

        return false;
    }

如果我有 DBDebug TRUE 那么它将异常传递给 CodeIgniter\Database\BaseConnection (下面的代码)

// Run the query for real
        try {
            $exception      = null;
            $this->resultID = $this->simpleQuery($query->getQuery());
        } catch (DatabaseException $exception) {
            $this->resultID = false;
        }

但是它永远不会传回控制器。 我在控制器中有 try/catch ,如下所示,但它永远不会出现,因为框架代码永远不会传回异常。 大家有什么想法吗? 以下代码来自我的控制器。

try{
 //...More code above
  $modelProducts = new ProductsModel();
            $modelProducts->insert($data_product);
 //..EXCEPTION IS LOGGED HERE IN LOGS AS INSERTED VALUE IS DUPLICATED
//FURTHER CODE KEEPS getting progressed.
}
catch(DatabaseException $e)
{            
    **// THIS NEVER GET CALLED, EVEN THOUGH THERE WAS MYSQL EXCEPTION LOGGED IN LOGS**
    log_message('error',  __NAMESPACE__ . " > " . __FUNCTION__ . $e);
}
catch(Exception $e) {  
    **// THIS NEVER GET CALLED, EVEN THOUGH THERE WAS MYSQL EXCEPTION LOGGED IN LOGS**          
    log_message('error', __NAMESPACE__ . " > " . __FUNCTION__ . $e);
}
php codeigniter codeigniter-4
1个回答
0
投票

如果其他人正在寻找答案,那么您可以通过两种方式进行。

  1. 正如@b126在评论中提到的,您可以使用db_error()。但请确保在数据库事务后立即检查此项。如果回滚后检查则不起作用。
  2. 第二种方法(我用过)是
    $this->db->transException(true)
    。这样,如果存在 DB 异常,那么它将被 try catch 块中的 DatabaseException 捕获。我实际上正在检查数据库异常中的“重复错误”。
<?php

// When DBDebug in the Database Config must be true.

use CodeIgniter\Database\Exceptions\DatabaseException;

try {
    $this->db->transException(true)->transStart();
    $this->db->query('AN SQL QUERY...');
    $this->db->query('ANOTHER QUERY...');
    $this->db->query('AND YET ANOTHER QUERY...');
    $this->db->transComplete();
} catch (DatabaseException $e) {
    // Automatically rolled back already.
    // Check if the exception message or error code indicates a duplicate entry error
    if (strpos($e->getMessage(), 'Duplicate entry') !== false || $e->getCode() === 1062) {
          //return error message you want
      } else {
          //return error message you want
      }      
}

您可以在这里阅读更多信息 - https://codeigniter4.github.io/CodeIgniter4/database/transactions.html#throwing-exceptions

© www.soinside.com 2019 - 2024. All rights reserved.