实现代码如下所示,我们知道了可以使用Telnet模拟http访问,也想试着使用socket来调用webservice接口,原因是默认的php Soap不起作用,可能需要繁琐的配置才能实现。但在使用fsockopen调用的时候也现出了一些问题:
- php中,单引号中是没有转义字符的,即\r\n是原始显示的
- http头部使用1.1的时候,可能会出现keep-alive模式,这种情况下需要使用Content-Length来判断body的长度,取出数据结束,而不应使用feof
- fgets()是一次读取一行;fread()是一次读取一个字符,后面可加数量
$content = '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
$content. = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'."\r\n";
$content. = ' <soap:Body>'."\r\n";
$content. = ' <QueryBalance xmlns="http://tempuri.org/">'."\r\n";
$content. = ' <userId>sg128</userId>'."\r\n";
$content. = ' </QueryBalance >'."\r\n";
$content. = ' </soap:Body>'."\r\n";
$content. = '</soap:Envelope>'."\r\n";
$fp = fsockopen('example.com', 80);
fwrite($fp, "POST /Service/UserService.asmx HTTP/1.0\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: text/xml; charset=utf-8\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "SOAPAction: \"http://tempuri.org/QueryBalance\"\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
header('Content-type: text/plain');
// $length = 0;
// $line = '';
// while($line !== "\r\n") {
// $line = fgets($fp);
// if(substr($line, 0, 15) === 'Content-Length:') {
// $length = intval(substr($line, 16));
// }
// }
// echo fread($fp, $length);
while (!feof($fp)) {
echo fgets($fp);
}
fclose($fp);