我已经花费了无数个小时来处理 PHP 中的 SOAP。现在我可以声称我对它了如指掌。 :)
第一个问题:SoapClient 和 cURL 用于不同的目的。 SoapClient 是关于 SOAP 的,cURL 是关于 HTTP 传输的。作为访问协议的 SOAP 比传输协议高一级。 SOAP 可以通过您选择的任何传输方式进行传输:通常 SOAP 文档(即纯 XML 文档)由 SMTP(即通过电子邮件)发送,以便穿越限制性防火墙。 cURL 只是在某处访问某些 Web 服务器的工具。
第二个问题:在 cURL 中花费在本地执行上的 Speedwise 时间将是最少的。但这将被此类代码的低质量所抵消,因为它不会遵循 SOAP 标准,并且必然会以某种方式失败(它甚至可能不会让您知道它)。通常在执行过程中,大部分时间都花在传输上(即通过慢速网络/繁忙的网络服务器),因此您将使用哪种方式并不重要。
现在让我们看看幕后花絮:PHP 中的 Soap 扩展是相当不完整的。快速搜索单词“bogus”会在代码中产生 33 个不同的位置。其中大多数是 php_encoding.c 。不幸的是,PHP SOAP 在某些情况下无法生成正确的 SOAP 或无法理解正确的 SOAP - 互操作性是一个问题。大多数问题都在 PHP 和 .NET SOAP 之间,但我想如果您尝试使用 cURL 访问 .NET SOAP,您需要的不仅仅是几行代码来实现它。幸运的是,普通 SOAP 在 PHP SOAP 中非常好,并且可以与其他 SOAP 实现一起使用。如果您想使用 SoapHeaders 或 mustUnderstand,请准备好做一场噩梦。 SoapHeaders 使用 cURL 相对容易。 mustUnderstand 在 cURL 中将很难做到。
使用 SoapClient 的主要好处是 WSDL(Web 服务描述语言)。基本上你可以这样做:
$client = new SoapClient("http://webserver.com/service.wsdl");
$client->executeRemoteFunction($paramters);
使用 cURL 您将无法做到这一点,因为它没有 WSDL 解析器。如果远程端将更改其规格 cURL 实现将惨遭失败并且不会让您知道。此时您可以说:但是如果远程 Web 服务器会默默地删除 executeRemoteFunction() 那么我也不知道!情况并非如此:SoapClient 抛出 SoapFault 异常,您需要捕获并处理它,否则您的脚本将停止并出现未处理的异常消息。无论哪种方式,您都会知道。
但是,不要指望 PHP SOAP 会为您做一些好事,例如类型检查。即使远程 WSDL 需要 xs:integer PHP SOAP 也会忽略它,并会发送您将提供的任何类型的静默。使用 cURL 进行类型检查?无法完成,因为一开始就没有 WSDL 支持。
在谈到 SOAP WSDL 时,请注意 PHP 会将 WSDL 缓存 7 天(默认设置)。开发过程中的快速 WSDL 更改很快就会给您带来麻烦:清除 WSDL 缓存并不总是那么容易。但另一方面,您可以在开发过程中完全禁用 WSDL 缓存:速度会下降,但至少您可以在没有“我不知道为什么它不能满足我的要求!”的情况下进行开发
因此,阅读 PHP SOAP 中的一些好东西后,您可能想知道是否有充分的理由将 cURL 用于 SOAP。我的回答是“是的”,有。不幸的是,PHP SOAP 无法创建某些类型的 SoapHeader 。因此,如果您使用这些高级的东西,您将需要使用 SoapClient 创建 SOAP 文档,然后使用一些 XML 工具(例如 PHP DOM)对其进行修改,然后使用 cURL 将其发送出去。但这完全是另一回事。
如果您只是从 PHP 中的 SOAP 开始,请帮自己一个忙,坚持使用 PHP SOAP 扩展,而不是 cURL。它是处理 SOAP 的更简洁的方式,速度快,可维护扩展(因此预计其互操作性最终会提高),它理解 WSDL 并提供良好的错误报告和处理。