2012-04-13 100 views
0

我爲Highrise的API編寫了一個非常基本的包裝類。它適用於Reads(GET),並且我剛開始爲Creates(POST)測試它。據我所知,這兩個請求(一個在命令行上,一個通過PHP的cURL庫)是相同的。相同的XML,相同的選項設置....只是一個有效,而另一個沒有。爲什麼這個cURL請求在命令行中工作,但不在PHP中?

任何幫助表示讚賞。我也把這個問題發佈到37signals開發者郵件列表中,但是stackoverflow通常更快地發現我的愚蠢錯誤...

這是我用PHP的cURL得到的錯誤(讓我覺得Highrise有解析XML字符串的問題):

<?xml version="1.0" encoding="UTF-8"?> <errors> <error>First name can't be blank</error> </errors> 

這是在命令行上是什麼在起作用:

curl -u 'my_api_key:X' 
    -H 'Content-type: application/xml' 
    -d '<?xml version="1.0" encoding="UTF-8"?> <person><first-name>Savos</first-name><last-name>Aren</last-name><title>Archmage</title><company-name>Winterhold College</company-name><contact-data><email-addresses/><phone-numbers><phone-number><number>555-555-5555</number><location>Home</location></phone-number><phone-number><number>555-555-5555</number><location>Work</location></phone-number><phone-number><number>555-555-5555</number><location>Mobile</location></phone-number></phone-numbers><addresses><address><city>Winterhold</city><country>Tamriel</country><state>Skyrim</state><street>Hall of the Elements, College of Winterhold</street><zip>99999</zip><location>Work</location></address></addresses></contact-data></person>' 
    https://myuserid.highrisehq.com/people.xml 

這裏是我的包裝類:

class HighriseAPICall { 
    protected $_timeout = 120; 
    protected $_url_prefix = 'https://'; 
    protected $_url_suffix = '.highrisehq.com'; 
    protected $_password = 'X'; 

    protected $_userpwd; 
    protected $_url; 

    public function __construct($api_key, $username) { 
     $this->_userpwd= $api_key . ':' . $this->_password; 
     $this->_url = $this->_url_prefix . $username . $this->_url_suffix; 
    } 

    /** 
    * Make the specified API call. 
    * @param string $action one of the four HTTP verbs supported by Highrise 
    * @param string $resource_name the Highrise resource to be accessed 
    * @param string $xml a well-formed XML string for a Highrise create, update, or delete request 
    * 
    * $xml parameter should include any query parameters as suggested by Highrise API documentation 
    * eg, if you want to GET all People, pass in "/people.xml" 
    * and if you want to get People by search term where field=value, 
    * then pass in "/people/search.xml?criteria[field]=value" 
    */ 
    public function makeAPICall($action,$resource_name,$xml=null) { 
     /* initialize curl session and set defaults for new API call */ 
     $curl = curl_init(); 
     curl_setopt($curl, CURLOPT_URL, $this->_url . $resource_name); 
     curl_setopt($curl, CURLOPT_USERPWD, $this->_userpwd); 
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 
     curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->_timeout); 
     /* if xml was passed in, set header and postfields */ 
     if (isset($xml)) { 
      curl_setopt($curl, CURLOPT_HTTPHEADER, 'Content-type: application/xml'); 
      curl_setopt($curl, CURLOPT_POSTFIELDS, "$xml"); 
     } 
     /* set action as custom request */ 
     curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $action); 
     /* get the string response from executing the curl session */ 
     $result = curl_exec($curl); 
     curl_close($curl); 

     // return the response as a simpleXMLElement 
     try { 
       $result_simplexml = new SimpleXMLElement($result); 
     } 
     catch (Exception $e) { 
       throw new Exception("Highrise API Call Error: " . $e->getMessage() . ", Response: " . $result); 
     } 
     if (!is_object($result_simplexml)) { 
       throw new Exception("Highrise API Call Error: Could not parse XML, Response: " . $result); 
     } 
     return $result_simplexml; 
    } 

} 
?> 

和簡單testpage我使用:

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title></title> 
    </head> 
    <body> 
     <?php 
      require_once('HighriseAPICall.class.php'); 
      $highrise_api_key = 'OBSCURED'; 
      $highrise_username = 'OBSCURED'; 
      $highrise_api = new HighriseAPICall($highrise_api_key, $highrise_username); 

      $person_xml ='<?xml version="1.0" encoding="UTF-8"?> <person><first-name>Savos</first-name><last-name>Aren</last-name><title>Archmage</title><company-name>Winterhold College</company-name><contact-data><email-addresses/><phone-numbers><phone-number><number>555-555-5555</number><location>Home</location></phone-number><phone-number><number>555-555-5555</number><location>Work</location></phone-number><phone-number><number>555-555-5555</number><location>Mobile</location></phone-number></phone-numbers><addresses><address><city>Winterhold</city><country>Tamriel</country><state>Skyrim</state><street>Hall of the Elements, College of Winterhold</street><zip>99999</zip><location>Work</location></address></addresses></contact-data></person>'; 

      $response = $highrise_api->makeAPICall('POST', '/people.xml', $person_xml); 
      echo htmlentities($response->asXML()); 
     ?> 
    </body> 
</html> 
+0

您可以使用curl的-D選項和CURLOPT_WRITEHEADER在這兩種情況下轉儲標題並將它們發佈到此處? – 2012-04-13 22:12:23

+0

@SebastiánGrignoli,剛剛看到這個。我會在週一早上這樣做,謝謝你的提示。從其他閱讀中,我認爲這可能是問題所在。 – 2012-04-13 23:57:03

回答

1

在我的包裝類,行:

curl_setopt($curl, CURLOPT_HTTPHEADER, 'Content-type: application/xml'); 

應該是:

curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/xml')); 
2

試試這行的,而不是你在你的腳本有什麼

if (isset($xml)) { 
     curl_setopt($curl, CURLOPT_POST, true); 
     curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/xml')); 
     curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); 
     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,false); 
     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST ,false); 
    } 
+0

我曾嘗試過,實際上,認爲這是客戶請求的問題。我剛纔再次檢查了一遍,提出了設置客戶請求的行,並添加了一行以將CURL_POST設置爲true,但沒有任何更改,同樣的錯誤。 – 2012-04-13 22:15:27

+0

你得到的錯誤是什麼? 在'curl_exec'行後面加上這一行: 'if($ result === false)die(curl_error($ curl));' – 2012-04-13 22:17:16

+0

我得到的錯誤是我原始文章中的第一行XML。 – 2012-04-13 22:24:09

相關問題