使用PHP SOAP 1.2调用WCF服务报错求助
解决PHP SoapClient访问WCF服务的"Error Fetching http headers"问题
针对你遇到的问题,结合WCF与PHP集成的常见坑,给出以下具体解决方向:
1. 修复代码语法错误
你的SoapClient构造函数末尾缺失闭合的),这会导致基础语法错误,先修正:
$client = new SoapClient($url, array( 'soap_version' => SOAP_1_2, 'exceptions' => true, 'trace' => true )); // 补上缺失的闭合括号
2. 正确配置超时参数
ini_set('default_socket_timeout', 600)放在try块内生效时机太晚,建议提前设置,并结合stream_context配置更细致的超时规则,同时在SoapClient选项中明确指定连接超时:
// 提前设置全局socket超时 ini_set('default_socket_timeout', 600); // 创建包含超时配置的流上下文 $streamContext = stream_context_create(array( 'http' => array( 'timeout' => 600, // HTTP请求整体超时 'connection_timeout' => 600 // 连接建立超时 ) )); // 初始化SoapClient时传入流上下文 $client = new SoapClient($url, array( 'soap_version' => SOAP_1_2, 'exceptions' => true, 'trace' => true, 'stream_context' => $streamContext, 'connection_timeout' => 600 ));
3. 确保HTTP基础认证生效
WCF的基础认证通常需要HTTP层面的Basic Auth,仅自定义SOAP Header可能无法通过验证。在流上下文中添加Authorization头:
$auth = base64_encode("$username:$password"); $streamContext = stream_context_create(array( 'http' => array( 'timeout' => 600, 'connection_timeout' => 600, 'header' => "Authorization: Basic $auth\r\n" ), // 若服务器使用自签名证书,添加以下两行跳过验证(生产环境谨慎使用) 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ) ));
4. 修正SOAP调用的参数结构
WCF服务通常要求参数被包裹在与方法名对应的数组中,调整__soapCall的参数格式:
$info = $client->__soapCall($func, array( $func => array('extRef' => "ABCD") ));
5. 验证SOAP Header的命名空间
确认WSDL中AuthHeader的命名空间是否为https://tempuri.org/,如果WCF服务使用了自定义命名空间,需要替换为WSDL中定义的正确值(可查看WSDL文件的<wsdl:definitions targetNamespace="...">节点确认)。
完整修正后的代码
<?php $wsdl = "https://example.com/NewServer/Services/WCFServices.svc?wsdl"; $url = $wsdl; $func = 'getValId'; $username = "admin"; $password = "admin"; // 设置全局超时 ini_set('default_socket_timeout', 600); // 构建HTTP基础认证头 $auth = base64_encode("$username:$password"); // 创建流上下文 $streamContext = stream_context_create(array( 'http' => array( 'timeout' => 600, 'connection_timeout' => 600, 'header' => "Authorization: Basic $auth\r\n" ), 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ) )); // 构建认证SOAP Header(确认命名空间与服务一致) $apiauth = array('UserName' => $username, 'Password' => $password); $authHeader = new SoapHeader('https://tempuri.org/', 'AuthHeader', $apiauth); // 初始化SoapClient $client = new SoapClient($url, array( 'soap_version' => SOAP_1_2, 'exceptions' => true, 'trace' => true, 'stream_context' => $streamContext, 'connection_timeout' => 600 )); try { $client->__setSoapHeaders($authHeader); // 修正参数结构 $info = $client->__soapCall($func, array( $func => array('extRef' => "ABCD") )); var_dump($info); } catch (SoapFault $fault) { // 打印请求/响应XML辅助调试 echo "Request XML:\n" . $client->__getLastRequest() . "\n"; echo "Response XML:\n" . $client->__getLastResponse() . "\n"; var_dump($fault); die; } ?>
额外调试建议
- 利用
__getLastRequest()和__getLastResponse()查看实际发送/接收的XML,排查参数、命名空间是否与WCF服务要求匹配。 - 用curl测试服务连通性,验证HTTP认证和请求格式:
curl -u admin:admin -H "Content-Type: application/soap+xml; charset=utf-8" -d @request.xml https://example.com/NewServer/Services/WCFServices.svc
其中request.xml为符合WCF规范的SOAP请求内容。
内容的提问来源于stack exchange,提问作者Indunil Withana
相关产品推荐
相关产品推荐

