我正在编写一个通过XML与服务器通信的脚本。我可以说我要对服务器的API提出成功请求,因为我可以在接收到的服务器上的日志中看到,但是我很难收到响应(XML(。我不拥有服务器,不幸的是无法修改发送响应的任何程序。
我不认为服务器指定文件的末尾,因此执行while (!feof($fp)) { ... }
挂起。不幸的是,我认为在阅读响应之前,我没有任何方法(据我所知(确定响应的大小。
我在做什么以及我尝试的事情:
function postXMLSocket ($server, $path, $port, $xmlDocument) {
$contentLength = strlen($xmlDocument);
$result = '';
// Handling error case in else statement below
if ($fp = @fsockopen($server, $port, $errno, $errstr, 30)) {
$out = "POST / HTTP/1.0rn";
$out .= "Host: ".$server."rn";
$out .= "Content-Type: text/xmlrn";
$out .= "Content-Length: ".$contentLength."rn";
$out .= "Connection: closern";
$out .= "rn"; // all headers sent
$out .= $xmlDocument;
fwrite($fp, $out);
// ATTEMPT 5: Read until we have a valid XML doc -- hangs
// libxml_use_internal_errors(true);
// do {
// $result .= fgets($fp, 128);
// $xmlTest = simplexml_load_string($result);
// } while ($xmlTest === false);
// ATTEMPT 4: Read X # of lines -- works but I can't know how many lines response will be
// for ($i = 0; $i < 10; $i++) {
// $result .= fgets($fp, 128);
// }
// ATTEMPT 3: Read until the lines being read are empty -- hangs
// do {
// $lineRead = fgets($fp, 500);
// $result .= $lineRead;
// } while (strlen($lineRead) > 0);
// ATTEMPT 2: Read the whole file w/ fread -- only reads part of file
// $result = fread($fp, 8192);
// ATTEMPT 1: Read to the EOF -- hangs
// while (!feof($fp)) {
// $result .= fgets($fp, 128);
// }
fclose($fp);
}
else {
// Could not connect to socket
return false;
}
return $result;
}
尝试描述:
1(首先,我只是尝试阅读行,直到到达文件的末尾。这一直在悬挂并导致时间耗尽,我认为这是因为服务器没有标记其响应的XML文件的末尾,因此它被捕获在无限的循环中。
2(第二我试图将响应读为一个整个文件。这奏效了,我得到了一些东西,但这是不完整的(似乎响应很大(。虽然这起作用,但我没有任何方法可以在阅读响应之前有多大,所以我认为这是一种选择。
3(接下来我尝试阅读,直到fgets
返回一个空字符串。我做出了一个假设,如果它通过文件末尾读取行,它将这样做,但这也悬挂。
4(对于此尝试读它。
5(这是我以为我变得聪明的地方。我知道响应将是XML,并且将包含在<Response>
节点中。因此,我以为我可以逃脱阅读,直到$result
变量包含有效的XML字符串,但这似乎也挂起。
使用较高级别的方法http请求可能会为您提供帮助。尝试以下操作:
$stringWithSomeXml = "your payload xml here";
postXml("www.google.com", "/path/on/server", 80, $stringWithSomeXml);
function postXml($server, $path, $port, $xmlPayload)
{
$ch = curl_init();
$path = ltrim($path, "/");
if ($port == 80) {
$url = "https://{$server}/{$path}";
} else {
$url = "https://{$server}:{$port}/{$path}";
}
echo "n$urln";
curl_setopt(
$ch,
CURLOPT_URL,
$url
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
[
"Content-type: application/xml",
"Content-Length: ".strlen($xmlPayload)
]
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlPayload);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($ch);
echo "length: " . strlen($result) . "n";
echo "content: " . $result . "n";
curl_close($ch);
}