我正在使用代码点火器REST-API(作者:philsturgeon Ref)
我对给定的API代码集有一个疑问。
我知道有一个函数和一个日志表"logs"来存储API请求(带有请求参数)。这很有效。
我想知道是否有一种方法可以从API获得响应并将其存储在同一个表中。
换句话说,请求日志是创建的,它是代码点火器中默认的内置功能。我还需要帮助存储响应。有办法吗?
首先在_log_request
函数中添加另一个传递响应参数,即
_log_request($authorized = FALSE)
至
_log_request($authorized = FALSE,$response="")
您可以在响应功能中传递响应输出,即
$this->_log_request($authorized = TRUE,$output);
在DB表中添加"response"字段以存储响应
这是更新的代码:
// 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);
}
很好的建议,senthilbp。但我认为每个API请求只有一个记录要好得多,每个请求的代码将创建两个记录,除了"响应"之外,所有字段都相同。所以这是我的选择。好的做法是不更改原始源代码,而是使用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()
内部调用
哇!