CodeIgniter-как поймать ошибки БД?
есть ли способ сделать CI бросить исключение когда он встречает ошибка БД вместо отображения сообщения типа:
Произошла Ошибка Базы Данных Номер Ошибки: 1054 Неизвестный столбец " foo "в предложении" where " SELECT * FROM (
FooBar
), гдеfoo
= '1'
примечание: Я хочу, чтобы это произошло только в одном контроллере. В других контроллерах я рад, что он отображает DB сообщения об ошибках.
10 ответов:
попробуйте эти функции CI
$this->db->_error_message(); (mysql_error equivalent) $this->db->_error_number(); (mysql_errno equivalent)
может, так:
$db_debug = $this->db->db_debug; //save setting $this->db->db_debug = FALSE; //disable debugging for queries $result = $this->db->query($sql); //run query //check for errors, etc $this->db->db_debug = $db_debug; //restore setting
в Codeigniter 3.0 (CI3), все, что вам нужно сделать, это
$this->db->error()
Если вам нужно получить последнюю возникшую ошибку, метод error () вернет массив, содержащий его код и сообщение
http://www.codeigniter.com/user_guide/database/queries.html#handling-errors
вы должны отключить отладку для базы данных в config / database.php ->
$db['default']['db_debug'] = FALSE;
это лучше для безопасности вашего сайта.
Я знаю, что эта тема старая, но на всякий случай у кого-то еще есть эта проблема. Это трюк, который я использовал, не касаясь классов CI db. Оставьте отладку включенной и в файле представления ошибок создайте исключение.
Итак, в вашей конфигурации db у вас есть :
$db['default']['db_debug'] = true;
затем на ваш взгляд ошибка файла БД, помоему в
application/errors/error_db.php
заменить все содержимое следующим:<?php $message = preg_replace('/(<\/?p>)+/', ' ', $message); throw new Exception("Database error occured with message : {$message}"); ?>
Так как файл представления будет вызван, ошибка всегда будет выдаваться как исключение, вы можете позже добавить различные представления для разных сред.
Я создал простую библиотеку для этого:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class exceptions { public function checkForError() { get_instance()->load->database(); $error = get_instance()->db->error(); if ($error['code']) throw new MySQLException($error); } } abstract class UserException extends Exception { public abstract function getUserMessage(); } class MySQLException extends UserException { private $errorNumber; private $errorMessage; public function __construct(array $error) { $this->errorNumber = "Error Code(" . $error['code'] . ")"; $this->errorMessage = $error['message']; } public function getUserMessage() { return array( "error" => array ( "code" => $this->errorNumber, "message" => $this->errorMessage ) ); } }
пример запроса:
function insertId($id){ $data = array( 'id' => $id, ); $this->db->insert('test', $data); $this->exceptions->checkForError(); return $this->db->insert_id(); }
и я могу поймать его таким образом в моем контроллере:
try { $this->insertThings->insertId("1"); } catch (UserException $error){ //do whatever you want when there is an mysql error }
использовать
$this->db->_error_message();
лучше для поиска ошибки.После завершения вашего сайта. Закройте сообщения об ошибках используя его
$db['default']['db_debug'] = FALSE;
вы измените его в базе данных вашей папки конфигурации.php
поместите этот код в файл с именем MY_Exceptions.php в папке application / core:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * Class dealing with errors as exceptions */ class MY_Exceptions extends CI_Exceptions { /** * Force exception throwing on erros */ public function show_error($heading, $message, $template = 'error_general', $status_code = 500) { set_status_header($status_code); $message = implode(" / ", (!is_array($message)) ? array($message) : $message); throw new CiError($message); } } /** * Captured error from Code Igniter */ class CiError extends Exception { }
это сделает все ошибки воспламенителя кода, которые будут рассматриваться как исключение (CiError). Затем включите всю отладку базы данных:
$db['default']['db_debug'] = true;
Если вы используете PDO, дополнительно ко всем ответам выше.
я регистрирую свои ошибки молча, как показано ниже
$q = $this->db->conn_id->prepare($query); if($q instanceof PDOStatement) { // go on with bind values and execute } else { $dbError = $this->db->error(); $this->Logger_model->logError('Db Error', date('Y-m-d H:i:s'), __METHOD__.' Line '.__LINE__, 'Code: '.$dbError['code'].' - '.'Message: '.$dbError['message']); }
отключить отладку ошибок.
$data_user = $this->getDataUser(); $id_user = $this->getId_user(); $this->db->db_debug = false; $this->db->where(['id' => $id_user]); $res = $this->db->update(self::$table, $data_user['user']); if(!$res) { $error = $this->db->error(); return $error; //return array $error['code'] & $error['message'] } else { return 1; }