无法使用cURL从XML POST获得服务器响应

时间:2019-05-30 16:15:58

标签: php xml curl

我已经完成了该项目的较难部分,但是cURL似乎不想合作。我不断收到来自服务器的空答复(可能没有POSTFIELDS数据正在发送)或API特定错误A-19,这是格式错误或类型错误的请求。如果我使用硬编码的字符串而不是必需的变量发送请求,则该请求可以正常工作。

我通过使用API​​文档提供的示例请求格式以及API文档提供的特定测试数据开始了该过程。在构建演示测试以开始解析数据的困难部分时,我使用了POSTMAN。一旦找出响应的所有解析内容,我就简单地从Postman那里获取了cURL代码,并对其进行了测试,然后就可以了。当我开始用POST设置的变量(例如,使用$_REQUEST[fname])替换诸如名称,姓氏等之类的变量时,出现了我的问题。我尝试使用下面的变量分配以及原始POST数据变量。 $output上的echo完全按预期工作,因此我很肯定POST值是可访问的。

  $state = $_REQUEST[state];
  $type = $_REQUEST[type];
  $street = $_REQUEST[street];
  $city = $_REQUEST[city];
  $zipcode = $_REQUEST[zipcode];
  $fname = $_REQUEST[fname];
  $lname = $_REQUEST[lname];
  $email = $_REQUEST[email];
  $phone = $_REQUEST[phone];
  $estCreditScore = $_REQUEST[estCreditScore];
  $estLoanAmount = $_REQUEST[estLoanAmount];
  $estDownPayment = $_REQUEST[estDownPayment];
  $monthlyIncome = $_REQUEST[monthlyIncome];
  $ssn = $_REQUEST[ssn];

$output = htmlspecialchars("<REQUEST_GROUP MISMOVersionID=\"2.3.1\">   <RECEIVING_PARTY _Name=\"8888\"/>    <REQUEST InternalAccountIdentifier=\"Identifier\" LoginAccountIdentifier=\"acc\" LoginAccountPassword=\"pass!\">        <REQUEST_DATA>            <CREDIT_REQUEST MISMOVersionID=\"2.3.1\">                <CREDIT_REQUEST_DATA CreditReportRequestActionType=\"Submit\" CreditReportType=\"Merge\">                    <CREDIT_REPOSITORY_INCLUDED _EquifaxIndicator=\"Y\" _ExperianIndicator=\"Y\" _TransUnionIndicator=\"Y\"/>                    <CREDIT_SCORE_MODEL_NAME _Type=\"EquifaxBeacon\"/>                    <CREDIT_SCORE_MODEL_NAME _Type=\"TransUnionEmpirica\"/>                </CREDIT_REQUEST_DATA>                <LOAN_APPLICATION>                    <BORROWER BorrowerID=\"BOR01\" _FirstName=\"$_REQUEST[fname]\" _LastName=\"$_REQUEST[lname]\" _PrintPositionType=\"Borrower\" _SSN=\"$_REQUEST[ssn]\">                        <_RESIDENCE _StreetAddress=\"$_REQUEST[street]\" _City=\"$_REQUEST[city]\" _State=\"$_REQUEST[state]\" _PostalCode=\"$_REQUEST[zipcode]\"/>                    </BORROWER>                                </LOAN_APPLICATION>            </CREDIT_REQUEST>        </REQUEST_DATA>    </REQUEST></REQUEST_GROUP>", ENT_XML1);


$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "url/url/url",
  CURLOPT_RETURNTRANSFER => 1,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30000,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_SSL_VERIFYHOST => false, //for testing on my dev machine only. To be removed before deployment
  CURLOPT_SSL_VERIFYPEER => false, //for testing on my dev machine only. To be removed before deployment
  CURLOPT_POSTFIELDS => $output,
  CURLOPT_HTTPHEADER => array(
    "Accept: */*",
    "Cache-Control: no-cache",
    "Connection: keep-alive",
    "Content-Type: text/xml",
    "Host: url/url",
    "User-Agent: PostmanRuntime/7.13.0",
    "accept-encoding: gzip, deflate",
    "content-length: 1426"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);






if ($err) {
  echo "cURL Error #:" . $err; 
} else {
  echo $response;
}    

转储$_REQUEST的输出:

array(12) {
 ["fname"]=> string(6) "Xavier"
 ["lname"]=> string(10) "Testcase10"
 ["ssn"]=> string(11) "030-00-0000"
 ["state"]=> string(2) "WA"
 ["type"]=> string(8) "Purchase"
 ["street"]=> string(14) "1121 N Main ST"
 ["city"]=> string(7) "Spokane"
 ["zipcode"]=> string(5) "99203"
 ["monthlyIncome"]=> string(4) "7500"
 ["estCreditScore"]=> string(3) "750"
 ["estLoanAmount"]=> string(6) "275000"
 ["estDownPayment"]=> string(5) "25000"
}

1 个答案:

答案 0 :(得分:0)

您说要在Content-Type标头中发送XML,但是随后将其发送为纯文本(通过htmlspecialchars()运行XML时得到的文本。)实际上,我们使用所有这些变量,创建并转义它们。尽管您确实应该使用适当的工具来构建XML,但是使用Heredoc块将使事情变得更容易。不需要大多数标题,但是如果您确实想滚动自己的“ Content-Length”标题,则需要在其中放置正确的值。

<?php

// test data
$_REQUEST = ["fname"=>"Xavier", "lname"=>"Testcase10", "ssn"=>"030-00-0000", "state"=>"WA", "type"=>"Purchase", "street"=>"1121 N Main ST", "city"=>"Spokane", "zipcode"=>"99203", "monthlyIncome"=>"7500", "estCreditScore"=>"750", "estLoanAmount"=>"275000", "estDownPayment"=>"25000"];

$api_url = "https://example.com/path";

$state = htmlspecialchars($_REQUEST['state']);
$type = htmlspecialchars($_REQUEST['type']);
$street = htmlspecialchars($_REQUEST['street']);
$city = htmlspecialchars($_REQUEST['city']);
$zipcode = htmlspecialchars($_REQUEST['zipcode']);
$fname = htmlspecialchars($_REQUEST['fname']);
$lname = htmlspecialchars($_REQUEST['lname']);
$email = htmlspecialchars($_REQUEST['email']);
$phone = htmlspecialchars($_REQUEST['phone']);
$estCreditScore = htmlspecialchars($_REQUEST['estCreditScore']);
$estLoanAmount = htmlspecialchars($_REQUEST['estLoanAmount']);
$estDownPayment = htmlspecialchars($_REQUEST['estDownPayment']);
$monthlyIncome = htmlspecialchars($_REQUEST['monthlyIncome']);
$ssn = htmlspecialchars($_REQUEST['ssn']);

$output = <<< XML
<?xml version="1.0"?>
<REQUEST_GROUP MISMOVersionID="2.3.1">
   <RECEIVING_PARTY _Name="8888"/>
   <REQUEST InternalAccountIdentifier="Identifier" LoginAccountIdentifier="acc" LoginAccountPassword="pass!">
        <REQUEST_DATA>
            <CREDIT_REQUEST MISMOVersionID="2.3.1">
                <CREDIT_REQUEST_DATA CreditReportRequestActionType="Submit" CreditReportType="Merge">
                    <CREDIT_REPOSITORY_INCLUDED _EquifaxIndicator="Y" _ExperianIndicator="Y" _TransUnionIndicator="Y"/>
                    <CREDIT_SCORE_MODEL_NAME _Type="EquifaxBeacon"/>
                    <CREDIT_SCORE_MODEL_NAME _Type="TransUnionEmpirica"/>
                </CREDIT_REQUEST_DATA>
                <LOAN_APPLICATION>
                    <BORROWER BorrowerID="BOR01" _FirstName="$fname" _LastName="$lname" _PrintPositionType="Borrower" _SSN="$ssn">
                        <_RESIDENCE _StreetAddress="$street" _City="$city" _State="$state" _PostalCode="$zipcode"/>
                    </BORROWER>
                </LOAN_APPLICATION>
            </CREDIT_REQUEST>
        </REQUEST_DATA>
    </REQUEST>
</REQUEST_GROUP>
XML;

$curl = curl_init($api_url);

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30000,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => $output,
    CURLOPT_HTTPHEADER => [
        "Content-Type: text/xml",
    ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

printf("Sent %d bytes to host<br/><br/>", strlen($output));
printf("Response: %s<br/><br/>", htmlspecialchars($response));
printf("Error: %s", htmlspecialchars($err));