我在php中使用soap创建一个客户端,用于.net中的web服务。 Web服务通过https运行,带有自签名证书,对于测试,我必须信任此证书而不安装它。
问题是我总是得到这个错误:
SOAP-ERROR:解析WSDL:无法从' https://winsystemsintl.com:54904/PSAService.svc?wsdl'加载:未能加载外部实体" https://winsystemsintl.com:54904/PSAService.svc?wsdl"。
这是我的代码:
$opts = [
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
],
'http'=>[
'user_agent' => 'PHPSoapClient'
]
];
// Initialize Soap Client
$this->client = new SoapClient($this->wsdl, array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2, 'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));
我能够使用wget获取wsd:
wget --secure-protocol = SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate
希望有人可以帮助我,非常感谢。
答案 0 :(得分:1)
问题是PHP在下载WSDL
文件时会忽略您的流上下文。解决方法是下载WSDL
文件,并将所有架构导入到本地文件系统(我在这里使用tidy
来打印XML):
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?wsdl
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd0
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd1
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd2
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd3
接下来,您必须编辑PSAService.svc?wsdl
(wget保存到的文件名)并将导入更改为指向本地系统而不是Web。在您喜欢的编辑器中使用替换所有功能,并将'https://winsystemsintl.com:54904/'
替换为''
:
示例强> 的之前:强>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0"
namespace="http://tempuri.org/" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1"
namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
</xsd:schema>
</wsdl:types>
<强>后:强>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="PSAService.svc?xsd=xsd0"
namespace="http://tempuri.org/" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd1"
namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd2"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd3"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
</xsd:schema>
</wsdl:types>
对每个下载的文件重复。
接下来,将代码更改为以下内容(我假设所有PHP / WSDL文件都在同一个文件夹中):
$opts = [
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
],
'http'=>[
'user_agent' => 'PHPSoapClient'
]
];
// Initialize Soap Client
$client = new SoapClient('PSAService.svc?wsdl', array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2, 'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));
var_dump($client->__getFunctions());
现在SoapClient
已跳过从网上下载WSDL
,您已准备好开始使用您的信息流上下文进行通话。