1

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

我有一个关于给定 API 代码集的查询/问题。

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

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

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

4

2 回答 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);
    }
于 2013-08-08T06:20:17.513 回答
1

伟大的建议,森希尔普。但我认为每个 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);
    }    
}

我希望代码足够清晰,但我将重点关注关键领域:

  1. 添加了类字段$_log_id;
  2. _log_request()修改为存储插入日志ID的方法
  3. 添加_log_response()了使用响应更新日志记录的方法
  4. _log_response()内部调用的方法response()

瞧!

于 2014-02-17T15:42:36.303 回答