如何使用curl PHP从redmine应用程序中获取所有问题

时间:2017-12-29 05:56:47

标签: php curl

这里我试图通过使用下面的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的新手。

1 个答案:

答案 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函数抛出异常。 (这可以防止内存泄漏)