【发布时间】:2015-10-01 16:52:06
【问题描述】:
我正在尝试从 PHP 调用 WCF 服务 (.NET)。这比仅使用 SoapClient 稍微复杂一些,因为服务使用 WS2007FederationHttpBinding 进行身份验证。
这是我目前正在使用的代码。我什至没有添加凭据,因为我不确定如何添加,但无论如何,我什至还没有遇到拒绝访问错误。
$wsdl = "https://slc.centershift.com/sandbox40/StoreService.svc?wsdl";
$client = new SoapClient($wsdl,array(
//'soap_version'=>SOAP_1_2 // default 1.1, but this gives 'Uncaught SoapFault exception: [HTTP] Error Fetching http headers'
));
$params = array();
$params['SiteID'] = 123;
$params['GetPromoData'] = false;
$ret = $client->GetSiteUnitData(array('GetSiteUnitData_Request'=>$params));
print_r($ret);
-
我应该指向哪个 WSDL?
-
@987654321@<strong>?wsdl</strong>
似乎很短,但包含对(注意wsdl0)@987654322@<strong>?wsdl=wsdl0</strong>的引用 -
@987654323@<strong>?singleWsdl</strong>
似乎什么都有。
-
是否需要指定 SOAP 1.2?当我这样做时,我得到一个连接超时 (
[HTTP] Error Fetching http headers)。如果我不这样做,则使用 SOAP 1.1 的默认值,我得到一个[HTTP] Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'。这是因为我还没有通过身份验证,还是因为我使用了错误的 SOAP 版本?如何在 PHP 中进行身份验证?这是相应的 .NET/C# 代码。我是否需要以某种方式将这些作为 SOAP 标头?还是我认为这一切都错了,我什至需要在调用该方法之前进行某种身份验证(根据我所读到的,我应该取回一个令牌,然后将其用于所有未来的方法调用——我我想我在an answer here on Stack Overflow 中看到了一个例子。
如果我使用 WSDL 和 SOAP 版本调用 $client->__getFunctions(),我将获得所有函数的有效列表,因此我假设其中任何一个都可以,而我真正的问题是身份验证。
与我交谈过的其他程序员曾花时间试图让它工作,但放弃了,而是在 .NET 中实现了一个代理。他们将参数从 PHP 传递到他们自己的不安全的 .NET 服务,该服务又调用此安全服务。它可以工作,但对我来说似乎效率极低,而且适得其反,因为 WCF 的目的是支持所有类型的客户端(甚至是非 HTTP 客户端!)。
我在 MSDN 上读过 How to: Create a WSFederationHttpBinding,但没有帮助。
【问题讨论】:
-
?wsdl 或 ?singleWsdl 都可以。前者引用了按目的拆分的多个文档,后者将所有文档集中在一个地方。 wsdl 确实指定了正在使用的soap 版本,所以在它下载了wsdl 之后仍然需要告诉它使用哪个soap 版本似乎很奇怪。如果除了 wsdl 之外还需要提供此基本信息,我会建议该库不成熟/质量差,我不希望您让联盟使用它。我建议找一个不同/更好的肥皂库。
-
@MattC 感谢您的评论。很高兴了解 WSDL,但希望肥皂库不是问题(它是原生 PHP 库)。我检查了 nuSoap,但看起来它没有任何优势。
-
我真的不想听起来刻薄,@ShaneN,但是内置到 PHP 中并不能保证质量。参见例如蹩脚的
mail()。没有使用 PHP 的 SOAP,所以我无能为力。 -
我试图至少通过编辑问题以使其更易于阅读来提供帮助。请将代码截图替换为带有实际代码的代码块。将代码发布为屏幕截图可以防止其他人摆弄它。
标签: php web-services wcf soap