这里我试图通过使用下面的curl php从Redmine获取所有问题是我使用的代码。
我的CURL.php: redmine / redmine_curl.php中的flie类文件
<?php # Redmine Api
class class_redmine{
function get_upload_token($filecontent){
global $redmine_url , $redmine_key;
$upload_url = $redmine_url.'uploads.json?key='.$redmine_key;
$request['type'] = 'post';
$request['content_type'] = 'application/octet-stream';
//$filecontent = file_get_contents('test.php');
return $token = $this->curl_redmine($upload_url,$request,$filecontent);
//$token->upload->token;
}
#Issue
function create_issue($post_data){
global $redmine_url , $redmine_key;
$issue_url = $redmine_url.'issues.json?key='.$redmine_key;
$request['type'] = 'post';
$request['content_type'] = 'application/json';
return $this->curl_redmine($issue_url,$request,$post_data);
}
function get_issue($issue_id='',$project_id=''){
global $redmine_url , $redmine_key;
if($project_id!=''){
$issue_url = $redmine_url.'issues.json?key='.$redmine_key.'&project_id='.$project_id;
}else{ $issue_url = ($issue_id=='')?$redmine_url.'issues.json?key='.$redmine_key : $redmine_url.'issues/'.$issue_id.'.json?key='.$redmine_key;
}
return $this->curl_redmine($issue_url,'','');
}
#Projects
function get_projects($project_id=''){
global $redmine_url , $redmine_key;
$proj_url = ($project_id=='')?$redmine_url.'projects.json?key='.$redmine_key : $redmine_url.'projects/'.$project_id.'.json?key='.$redmine_key;
return $this->curl_redmine($proj_url,'','');
}
#Curl
function curl_redmine($redmine_url,$request='',$post_data=''){
if(!isset($request['type'])){ $request['type']=null; }
if(!isset($request['content_type'])){ $request['content_type']=null; }
//Create a curl object
$ch = curl_init();
//Set the useragent
$agent = $_SERVER["HTTP_USER_AGENT"];
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
//Set the URL
curl_setopt($ch, CURLOPT_URL, $redmine_url );
if($request['type'] == 'post'){
//This is a POST query
curl_setopt($ch, CURLOPT_POST,1);
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
//Set the post data
curl_setopt($ch, CURLOPT_POSTFIELDS,$post_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: '.$request['content_type'],
'Content-Length: ' . strlen($post_data))
);
}
//We want the content after the query
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//Follow Location redirects
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
/*
Set the cookie storing files
Cookie files are necessary since we are logging and session data needs to be saved
*/
//curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//Execute the action to login
$postResult = curl_exec($ch);
//if($postResult == false){ return $info = curl_getinfo($ch);}
$response = json_decode($postResult);
//echo '<pre>'; print_r($response); echo '</pre>';
return $response;
}
}//class_redmine
?>
这是我的example.php
<?php
function get_redmine($methodName='',$data=''){
global $redmine_url , $redmine_key;
$redmine_url = 'http://192.168.12.231:80/';
$redmine_key = 'API KEY';
include_once('curlcall.php');
$obj_redmine = new class_redmine();
#check Auth
$res = $obj_redmine->get_projects();
if(!isset($res->projects) || (isset($res->total_count) && ($res->total_count)==0)){ return -1; }
switch($methodName){
case 'check_status' : return $login_integrate;
##check redmine integration in vision break;
##Project
case 'projectAll' : return $obj_redmine->get_projects(); #used
break;
case 'projectById' : return $obj_redmine->get_projects($data['project_id']);
break;
##Issues
case 'issueAll' : return $obj_redmine->get_issue();
break;
case 'issueByProjectId' : return $obj_redmine->get_issue('',$data['project_id']);
break;
case 'uploadFileToIssue' : return $obj_redmine->get_upload_token($data);
break;
default: return 0;
}
}
#get all issue
$res = get_redmine('issueAll');
echo '<pre>';print_r($res);
?>
这段代码只提供了25条记录。在我的输出结尾,它就是这样说的 总数:201 偏移:0 限制:25 我无法理解如何解决所有问题请帮助任何人,我是php的新手。
答案 0 :(得分:0)
答案全部在the API docs,如果您只是懒得阅读它。使用limit参数获取更多结果,使用offset参数加载更多
/issues.json?offset=0&limit=100
会获取前100个问题
/issues.json?offset=100&limit=100
将获取接下来的100个问题,依此类推。
...但你应该做的第一件事就是让你的代码格式化,因为没有格式化的东西很难阅读。然后摆脱这一行'Content-Length: ' . strlen ( $post_data )
因为卷曲会自动添加标题,如果你不卷曲,卷曲不会做任何错别字,也不会错误地计算长度,不像我们的程序员( curl在每次提交时运行自动化测试,以确保内容长度正确,我打赌这不是你的测试套件的一部分),然后摆脱这个
if (! isset ( $request ['content_type'] )) {
$request ['content_type'] = null;
}
因为它永远不应该为null。为了将来参考,如果你真的不知道它应该是什么,请将它设置为application/octet-stream
,但在这种情况下即使这是错误的,因为API文档说唯一支持的POST编码是{ {1}}和application/json
,所以正确的做法是:
application/xml
至于获取所有问题,首先发出请求以查看有多少问题,然后使用limit = number_of_issues发出第二个请求,如下所示
if (isset ( $request ['content_type'] ) && $request ['content_type'] !== 'application/json' && $request ['content_type'] !== 'application/xml') {
throw new \InvalidArgumentException ( 'invalid content-type specified. supported types are "application/json" and "application/xml"' );
}
if($request ['type'] === 'post' && !isset($request ['content_type'])){
throw new \LogicException('no content-type was specified for this POST request, which is required. supported types are "application/json" and "application/xml"');
}
将它们放在一起,你得到了这个
if (! $issue_id) {
// first we check how many issues there are (OPTIMIZEME: there is probably a more efficient way to do this, for example limit=0 ?)
$issues_url .= '&limit=1';
$number_of_issues = $this->curl_redmine ( $issue_url, '', '' ) ['total_count'];
$issue_url = substr ( $issues_url, 0, - 1 ) . $number_of_issues;
}
(顺便说一句,这对我来说是完全未经测试的。)
您应该修复的另一个问题是您的卷曲代码完全执行而没有错误检测。例如,如果设置选项时出现问题,curl_setopt将返回bool(false),如果在传输过程中出现问题,curl_exec()将返回bool(false),为此添加错误检测。这些功能应该很容易:
<?php
// Redmine Api
class class_redmine {
function get_upload_token($filecontent) {
global $redmine_url, $redmine_key;
$upload_url = $redmine_url . 'uploads.json?key=' . $redmine_key;
$request ['type'] = 'post';
$request ['content_type'] = 'application/octet-stream';
// $filecontent = file_get_contents('test.php');
return $token = $this->curl_redmine ( $upload_url, $request, $filecontent );
// $token->upload->token;
}
// Issue
function create_issue($post_data) {
global $redmine_url, $redmine_key;
$issue_url = $redmine_url . 'issues.json?key=' . $redmine_key;
$request ['type'] = 'post';
$request ['content_type'] = 'application/json';
return $this->curl_redmine ( $issue_url, $request, $post_data );
}
function get_issue($issue_id = '', $project_id = '') {
global $redmine_url, $redmine_key;
if ($project_id != '') {
$issue_url = $redmine_url . 'issues.json?key=' . $redmine_key . '&project_id=' . $project_id;
} else {
$issue_url = ($issue_id == '') ? $redmine_url . 'issues.json?key=' . $redmine_key : $redmine_url . 'issues/' . $issue_id . '.json?key=' . $redmine_key;
}
if (! $issue_id) {
// first we check how many issues there are (OPTIMIZEME: there is probably a more efficient way to do this, for example limit=0 ?)
$issues_url .= '&limit=1';
$number_of_issues = $this->curl_redmine ( $issue_url, '', '' ) ['total_count'];
$issue_url = substr ( $issues_url, 0, - 1 ) . $number_of_issues;
}
return $this->curl_redmine ( $issue_url, '', '' );
}
// Projects
function get_projects($project_id = '') {
global $redmine_url, $redmine_key;
$proj_url = ($project_id == '') ? $redmine_url . 'projects.json?key=' . $redmine_key : $redmine_url . 'projects/' . $project_id . '.json?key=' . $redmine_key;
return $this->curl_redmine ( $proj_url, '', '' );
}
// Curl
function curl_redmine($redmine_url, $request = '', $post_data = '') {
if (! isset ( $request ['type'] )) {
$request ['type'] = null;
}
if (isset ( $request ['content_type'] ) && $request ['content_type'] !== 'application/json' && $request ['content_type'] !== 'application/xml') {
throw new \InvalidArgumentException ( 'invalid content-type specified. supported types are "application/json" and "application/xml"' );
}
if ($request ['type'] === 'post' && ! isset ( $request ['content_type'] )) {
throw new \LogicException ( 'no content-type was specified for this POST request, which is required. supported types are "application/json" and "application/xml"' );
}
// Create a curl object
$ch = curl_init ();
// Set the useragent
$agent = $_SERVER ["HTTP_USER_AGENT"];
curl_setopt ( $ch, CURLOPT_USERAGENT, $agent );
// Set the URL
curl_setopt ( $ch, CURLOPT_URL, $redmine_url );
if ($request ['type'] == 'post') {
// This is a POST query
curl_setopt ( $ch, CURLOPT_POST, 1 );
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
// Set the post data
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
'Content-Type: ' . $request ['content_type']
) );
}
// We want the content after the query
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
// Follow Location redirects
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
/*
* Set the cookie storing files
* Cookie files are necessary since we are logging and session data needs to be saved
*/
// curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
// curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
// Execute the action to login
$postResult = curl_exec ( $ch );
// if($postResult == false){ return $info = curl_getinfo($ch);}
$response = json_decode ( $postResult );
// echo '<pre>'; print_r($response); echo '</pre>';
return $response;
}
}//class_redmine
并且为了确保你没有泄漏任何内存,你可以将它全部包裹在function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ):bool{
$ret=curl_setopt($ch,$option,$value);
if($ret!==true){
//option should be obvious by stack trace
throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return true;
}
function ecurl_exec ( /*resource*/$ch):bool{
$ret=curl_exec($ch);
if($ret===false){
throw new RuntimeException ( 'curl_exec() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return $ret;
}
function return_var_dump(/*...*/){
$args = func_get_args ();
ob_start ();
call_user_func_array ( 'var_dump', $args );
return ob_get_clean ();
}
周围,确保始终调用curl_close,无论哪个curl函数抛出异常。 (这可以防止内存泄漏)