droos02800
droos02800
2017-11-16 11:00

如何在CodeIgniter中发生致命错误后操纵数据库?

已采纳

I'm trying to store in to the database diferent kind of errors and stranges behaviours in my Codeigniter. For these to not be an exception I would like to store php Fatal errors also. To archive this I proceded this way:

Created an override of the CI_Log class named MY_Log and stored it in application/core. The code in that class looks like this:

class MY_Log extends CI_Log {

    public function __construct(){

        parent::__construct();

    }

    function write_log($level = 'error', $msg, $php_error = FALSE){

        $result = parent::write_log($level, $msg, $php_error);

        if((require_once APPPATH.'libraries/Utils.php')== TRUE){
            if ($result == TRUE && strtoupper($level) == 'ERROR') {

                $utils = new Utils();
                $message = "An error occurred: 

";
                $message .= $level.' - '.date($this->_date_fmt). ' --> '.$msg."
";
                $utils->log_petition_if_required(date("Y-m-d H:i:s", time() + 86400), 0, "", 500, $message);
            }
        }


        return $result;

    }
}

This class actually caches the error correctly and redirects the functionality towards the 'Utils' library just right. The code in the library looks like this:

class Utils
{
    protected $CI;

    public function __construct()
    {
        $this->CI =& get_instance();
    }
    public function log_petition_if_required($date_log, $user_id, $post_data, $http_code, $output){

        $date_now = date("Y-m-d H:i:s");
        if(!empty($date_log) && $date_log>$date_now)
        {
            $url = $_SERVER['HTTP_HOST'].str_replace('/index.php','',$_SERVER['PHP_SELF']).'?'.$_SERVER['QUERY_STRING'];

            $insert_data = [
                'user_id' => $user_id,
                'date' => $date_now,
                'url' => $url,
                'post_data' => $post_data,
                'status' => $http_code,
                'response' => $output
            ];

            $sql = 'INSERT INTO activity_log (user_id, activity_date, url, post_data, http_code, response) VALUES (?,?,?,?,?,?)';

            //This condition is my futile intent of loading the database functionality and everything seems to work as expected till this point
            if(empty($this->CI)){
                $this->CI = & get_instance();
                $this->CI->load->database();
            }

            $query = $this->CI->db->query($sql, $insert_data);
        }
    }
}

So I've been having problems in this last lines in the log_petition_if_required function, loading the database functionality and executing the query.

Currently getting this error:

Fatal error: Call to a member function database() on a non-object in C:\wamp\www\appname\application\libraries\Utils.php on line $this->CI->load->database();

Which is the correct way to call the Loader class and get the database under this circumstances? Should I proceed in another way?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dongxing8766 dongxing8766 4年前

    As the user @DFriend stated in this question:

    Extending CI_Log is not going to work if you need to access other libraries. The reason is CI_Log is created long before $CI is created so no "instance" is available for &get_instance() to return.

    $this->load doesn't work because $this is not a controller ($this and $CI point to the same object) and the class load ('CI_Loader') hasn't been created yet either.

    The way I was proceeding doesn't look like the way to go. Since extending the CI_Log class has clear limitations as the modification of the core class itself.

    For the moment and since it is a temporal modification I will proceed overriding the CI_Log class and using plain PHP to complete the task.

    点赞 评论 复制链接分享

相关推荐