6

Can I change the database config per method in a controller?

$db['default']['db_debug'] = TRUE;

The default is TRUE, while I need to make it false in a certain method to catch the error and do something else (for example show 404 page).

When I tried $this->config->load('database') it fails.

Another question :

Can I check an incorrect query and catch it to some variables rather than displaying it to users other than setting the db_debug config to FALSE?

gmsantos
  • 1,412
  • 22
  • 30
Henson
  • 5,563
  • 12
  • 46
  • 60

5 Answers5

15

I checked the code of system/database/DB_Driver and found that:

$this->db->db_debug = FALSE;

will work in my controller to enable/disable the debug thing on the fly.

Muhammad Raheel
  • 19,823
  • 7
  • 67
  • 103
Antonio Gallo
  • 178
  • 2
  • 8
  • When I used this approach, it did work to turn off debugging but it then seemed to "turn off" my Exception handling. I can no longer catch(Exception $e) and then use $e->getMessage. I get the message that Exception::getMessage is undefined! – Zac Imboden Nov 28 '17 at 20:07
  • @ZacImboden dunno we're talking about codeigniter2 here - i can not say how this changed in v3 or latest – Antonio Gallo Nov 29 '17 at 20:55
  • I apologize. I found that the turning off of exception handling wasn't actually occurring. I had a syntax error in one try/catch block that was causing the issue and setting debug to false was simply exposing it. – Zac Imboden Dec 05 '17 at 19:32
3

Expanding on the answer by comenk, you can extend the database class and implement various methods by which to achieve your goal.

First, you'll need to extend the core Loader class by creating a MY_Loader.php file

class MY_Loader extends CI_Loader
{
    function __construct()
    {
        parent::__construct();
    }

    /**
     * Load the Standard and/or Extended Database function & Driver class
     *
     * @access  public
     * @return  string
     */
    function database( $params = '', $return = FALSE, $active_record = NULL )
    {
        $ci =& get_instance();

        if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($ci->db) AND is_object($ci->db))
        {
            return FALSE;
        }

        $my_db      = config_item('subclass_prefix').'DB';
        $my_db_file = APPPATH.'core/'.$my_db.EXT;

        if(file_exists($my_db_file))
        {
            require_once($my_db_file);
        }
        else
        {
            require_once(BASEPATH.'database/DB'.EXT);
        }

        // Load the DB class
        $db =& DB($params, $active_record);

        $my_driver      = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver';
        $my_driver_file = APPPATH.'core/'.$my_driver.EXT;

        if(file_exists($my_driver_file))
        {
            require_once($my_driver_file);
            $db = new $my_driver(get_object_vars($db));
        }

        if ($return === TRUE)
        {
            return $db;
        }

        // Initialize the db variable.  Needed to prevent
        // reference errors with some configurations
        $ci->db = '';
        $ci->db = $db;
    }
}

By implementing the above this will allow you to create a MY_DB_mysqli_driver.php whereby mysqli is replaced by whatever driver you're using in your CI database.php config.

At this point you'd add comenk's answer to MY_DB_mysqli_driver.php

function debug_on() {
     return $this->db_debug = TRUE;
}

function debug_off() {
     return $this->db_debug = FALSE;
}

function in_error() {
     return (bool) $this->_error_number();
}

Then in your model/controller,

$this->db->debug_off();

$this->db->query('SELECT * FROM `table`');

if( $this->db->in_error() ) {
    show_404();
}

$this->db->debug_on();
Ben Swinburne
  • 25,669
  • 10
  • 69
  • 108
1

$this->db->db_debug = 0; // 0: off, 1: on That worx for me... You can look at the $GLOBALS variable to locate this generic setting.

1

you must add function on system/database/DB_driver.php

function debug_on()
{
     $this->db_debug = TRUE;
     return TRUE;
}

function debug_off()
{
     $this->db_debug = FALSE;
     return FALSE;
}

after that you can simply do this command to changes at run-time

$this->db->debug_off();
$this->db->reconnect();
comenk
  • 69
  • 2
  • 10
  • is there any way without touching the core (system) files? – Henson Jan 16 '12 at 09:10
  • I think is not possible to do that without touch the core system, because as long as I know CodeIgniter not provide command to do that. – comenk Jan 17 '12 at 04:29
0

To hide bad SQL (and other errors) from users, you need to set the php error reporting level. CodeIgniter ships in basically development mode.

Go to index.php and replace this

error_reporting(E_ALL);

with this

error_reporting(0);

This is the quick way to do it. You can also implement this using a hook, so you don't have to touch CI files. You can also add logic to that hook so that it only sets it on the production server.

For debugging SQL, you can create a class that inherits from CI_Model, then create all your model classes to extend that class. In that class, you can add code for running queries that writes the queries to the log so that you can debug them easier. This won't help if the query itself is bad, but you should be able to figure that out before you get to that point.

minboost
  • 2,555
  • 1
  • 15
  • 15
  • error_reporting(0) will not prevent displaying query error. The only way to prevent query error is to set $db['default']['db_debug'] to FALSE, but then again, the site will only display blank page. What I want is to redirect users to 404 page or somewhere so even if there are query errors, the errors will be logged but the user will be redirected to 404. – Henson Oct 21 '11 at 03:00