首页 文章

Codeigniter REST API响应日志

提问于
浏览
1

我正在使用codeigniter REST-API(作者:philsturgeon Ref

我有一组API代码的查询/问题 .

我知道有一个函数和一个日志表'logs'来存储API请求(带有请求参数) . 这很好用 .

我想知道有没有办法从API获取响应并将其存储在同一个表中 .

换句话说,创建请求日志并在codeigniter中创建默认的内置功能 . 我还需要帮助存储响应 . 有办法吗?

2 回答

  • 2

    首先,在 _log_request 函数中为通过响应添加另一个参数,即

    _log_request($authorized = FALSE)

    _log_request($authorized = FALSE,$response="")

    您可以在响应函数中传递响应输出,即

    $this->_log_request($authorized = TRUE,$output);

    在数据库表中添加“响应”字段以存储响应

    这是更新的代码:

    // Request Parameter Log function
    protected function _log_request($authorized = FALSE,$response="")
        {
            return $this->rest->db->insert(config_item('rest_logs_table'), array(
                        'uri' => $this->uri->uri_string(),
                        'method' => $this->request->method,
                        'params' => $this->_args ? (config_item('rest_logs_json_params') ? json_encode($this->_args) : serialize($this->_args)) : null,
                        'ip_address' => $this->input->ip_address(),
                        'time' => function_exists('now') ? now() : time(),
                        'authorized' => $authorized,
                        'response' => $response
                    ));
        }
    
    // Response function 
    public function response($data = array(), $http_code = null)
        {
            global $CFG;
    
            // If data is empty and not code provide, error and bail
            if (empty($data) && $http_code === null)
            {
                $http_code = 404;
    
                // create the output variable here in the case of $this->response(array());
                $output = NULL;
            }
    
            // If data is empty but http code provided, keep the output empty
            else if (empty($data) && is_numeric($http_code))
            {
                $output = NULL;
            }
    
            // Otherwise (if no data but 200 provided) or some data, carry on camping!
            else
            {
                // Is compression requested?
                if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
                {
                    if (extension_loaded('zlib'))
                    {
                        if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
                        {
                            ob_start('ob_gzhandler');
                        }
                    }
                }
    
                is_numeric($http_code) OR $http_code = 200;
    
                // If the format method exists, call and return the output in that format
                if (method_exists($this, '_format_'.$this->response->format))
                {
                    // Set the correct format header
                    header('Content-Type: '.$this->_supported_formats[$this->response->format]);
    
                    $output = $this->{'_format_'.$this->response->format}($data);
                }
    
                // If the format method exists, call and return the output in that format
                elseif (method_exists($this->format, 'to_'.$this->response->format))
                {
                    // Set the correct format header
                    header('Content-Type: '.$this->_supported_formats[$this->response->format]);
    
                    $output = $this->format->factory($data)->{'to_'.$this->response->format}();
                }
    
                // Format not supported, output directly
                else
                {
                    $output = $data;
                }
            }
    
            header('HTTP/1.1: ' . $http_code);
            header('Status: ' . $http_code);
    
            // If zlib.output_compression is enabled it will compress the output,
            // but it will not modify the content-length header to compensate for
            // the reduction, causing the browser to hang waiting for more data.
            // We'll just skip content-length in those cases.
            if ( ! $this->_zlib_oc && ! $CFG->item('compress_output'))
            {
                header('Content-Length: ' . strlen($output));
            }
            if (config_item('rest_enable_logging'))
            {
            $this->_log_request($authorized = TRUE,$output);
            }
    
            exit($output);
        }
    
  • 1

    很棒的建议,senthilbp . 但我认为每个API请求只有一条记录要好得多,每个请求的代码将创建2条记录,除了“响应”之外,所有相同的字段 . 所以有我的选择 . 好的做法不是改变原始的源代码,而是使用OOP的优点并继承自己的类

    abstract class MY_REST_Controller extends REST_Controller
    {
        /**
         * PK from $config['rest_logs_table'] table for last inserted log.
         *
         * @var integer|null
         */
        protected $_log_id;
    
        /**
         * Log request
         *
         * Record the entry for awesomeness purposes
         *
         * @param boolean $authorized
         * @return object
         */
        protected function _log_request($authorized = FALSE)
        {
            $res = $this->rest->db->insert(config_item('rest_logs_table'), array(
                        'uri' => $this->uri->uri_string(),
                        'method' => $this->request->method,
                        'params' => $this->_args ? (config_item('rest_logs_json_params') ? json_encode($this->_args) : serialize($this->_args)) : null,
                        'api_key' => isset($this->rest->key) ? $this->rest->key : '',
                        'ip_address' => $this->input->ip_address(),
                        'time' => function_exists('now') ? now() : time(),
                        'authorized' => $authorized
                    ));
            $this->_log_id = $this->db->insert_id();
            return $res;
        }
    
        /**
         * Log request response, update existing record, created by @see _log_request()
         *
         * @param string $response
         * @return object
         */
        protected function _log_response($response="")
        {
            if(!$this->_log_id)
            {
                return;
            }
            $log_data['response'] = $response;
            $this->rest->db->where('id', $this->_log_id);
            $this->rest->db->where('response', NULL);// to prevent overwriting
            return $this->rest->db->update(config_item('rest_logs_table'), $log_data);
        }
    
        /**
         * Response
         *
         * Takes pure data and optionally a status code, then creates the response.
         *
         * @param array $data
         * @param null|int $http_code
         */
        public function response($data = array(), $http_code = null)
        {
            global $CFG;
    
            // If data is empty and not code provide, error and bail
            if (empty($data) && $http_code === null)
            {
                $http_code = 404;
    
                // create the output variable here in the case of $this->response(array());
                $output = NULL;
            }
    
            // If data is empty but http code provided, keep the output empty
            else if (empty($data) && is_numeric($http_code))
            {
                $output = NULL;
            }
    
            // Otherwise (if no data but 200 provided) or some data, carry on camping!
            else
            {
                // Is compression requested?
                if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
                {
                    if (extension_loaded('zlib'))
                    {
                        if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
                        {
                            ob_start('ob_gzhandler');
                        }
                    }
                }
    
                is_numeric($http_code) OR $http_code = 200;
    
                // If the format method exists, call and return the output in that format
                if (method_exists($this, '_format_'.$this->response->format))
                {
                    // Set the correct format header
                    header('Content-Type: '.$this->_supported_formats[$this->response->format]);
    
                    $output = $this->{'_format_'.$this->response->format}($data);
                }
    
                // If the format method exists, call and return the output in that format
                elseif (method_exists($this->format, 'to_'.$this->response->format))
                {
                    // Set the correct format header
                    header('Content-Type: '.$this->_supported_formats[$this->response->format]);
    
                    $output = $this->format->factory($data)->{'to_'.$this->response->format}();
                }
    
                // Format not supported, output directly
                else
                {
                    $output = $data;
                }
            }
    
            header('HTTP/1.1: ' . $http_code);
            header('Status: ' . $http_code);
    
            // If zlib.output_compression is enabled it will compress the output,
            // but it will not modify the content-length header to compensate for
            // the reduction, causing the browser to hang waiting for more data.
            // We'll just skip content-length in those cases.
            if ( ! $this->_zlib_oc && ! $CFG->item('compress_output'))
            {
                header('Content-Length: ' . strlen($output));
            }
    
            if (config_item('rest_enable_logging'))
            {
                $this->_log_response($output);
            }
    
            exit($output);
        }    
    }
    

    我希望代码足够明确但我会关注关键领域:

    • 添加了类字段 $_log_id;

    • 方法 _log_request() 已修改为存储插入日志的ID

    • 添加方法 _log_response() 以更新带有响应的日志记录

    • 方法 _log_response() 内部调用 response()

    瞧!

相关问题