从 NuSoap 切换到 PHP5 Soap - 需要快速启动
这是我试图拨打的电话:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:SessionHeader xmlns:urn="http://www.mywebservice.com/webservices/SoapService" xmlns="http://www.mywebservice.com/webservices/SoapService" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:sessionId xmlns:urn="http://www.mywebservice.com/webservices/SoapService">LOGINTOKEN=your instance name</urn:sessionId>
</urn:SessionHeader>
</soap:Header>
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns2:login xmlns:ns2="http://www.mywebservice.com/webservices/SoapService">
<wsUser>
<entityId>0</entityId>
<password>your password</password>
<username>your username</username>
</wsUser>
</ns2:login>
</soap:Body>
但我无法找到如何在 PHP5 的 Soap 中设置自定义标头。使用 nuSoap,我可以将整个内容放入一个变量中,然后使用 $client->setHeader($headerVar)
但我在 PHP 中找不到类似的内容。如果我能复制这个调用,我就能弄清楚剩下的事情。任何帮助将不胜感激!
提前致谢!
更新:我已经浏览了一个又一个教程,并阅读了 PHP 文档,但似乎没有任何效果。我可以用curl(以及nuSoap)做我想做的事情,但我认为原生PHP5 Soap会更容易,也可能更稳定。我想不是......
更新2 这是我正在尝试的代码:
$soapurl = 'http://www.mywebservice.com/webservices/SoapService?wsdl';
$client = new SoapClient($soapurl,array('trace'=>true));
$token = "LOGINTOKEN=your instance name";
$header = new SoapHeader('http://www.mywebservice.com/webservices/SoapService', 'SessionHeader', array('sessionId' => $token));
$client->__setSoapHeaders($header);
$client->login(array("wsUser" => array('entityId'=>'0','username'=>'my username','password'=>'my password')));
以及我收到的错误:
**Fatal error**: Uncaught SoapFault exception: [ns1:InvalidSecurity] An error was discovered processing the <wsse:Security> header in C:\www\soap\index.php:12 Stack trace: #0 C:\www\soap\index.php(12): SoapClient->__call('login', Array) #1 C:\www\soap\index.php(12): SoapClient->login(Array) #2 {main} thrown in C:\www\soap\index.php on line 12
更新 3 因此,看起来“sessionId”作为“key”发送,而令牌作为“value”发送。
*REQUEST*:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.mywebservice.com/webservices/SoapService">
<SOAP-ENV:Header>
<ns1:SessionHeader><item><key>sessionId</key><value>LOGINTOKEN=my token</value></item>
</ns1:SessionHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ns1:login><wsUser><entityId>0</entityId><password>my password</password><username>my username</username></wsUser></ns1:login></SOAP-ENV:Body></SOAP-ENV:Envelope>
Here's the call I'm trying to make:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:SessionHeader xmlns:urn="http://www.mywebservice.com/webservices/SoapService" xmlns="http://www.mywebservice.com/webservices/SoapService" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:sessionId xmlns:urn="http://www.mywebservice.com/webservices/SoapService">LOGINTOKEN=your instance name</urn:sessionId>
</urn:SessionHeader>
</soap:Header>
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns2:login xmlns:ns2="http://www.mywebservice.com/webservices/SoapService">
<wsUser>
<entityId>0</entityId>
<password>your password</password>
<username>your username</username>
</wsUser>
</ns2:login>
</soap:Body>
But I'm having trouble finding out how to set up the custom headers in PHP5's Soap. With nuSoap I could just put the whole thing into a variable and then use $client->setHeader($headerVar)
but I can't find anything similar in PHP. If I could replicate this one call, I can figure the rest out. Any help would be appreciated!
Thanks in advance!
Update: I've gone through tutorial after tutorial, and read the PHP docs, but nothing seems to work. I can do what I want with curl (as well as nuSoap) but I thought the native PHP5 Soap would be easier and possibly more stable. I guess not...
Update 2
Here's the code I'm trying:
$soapurl = 'http://www.mywebservice.com/webservices/SoapService?wsdl';
$client = new SoapClient($soapurl,array('trace'=>true));
$token = "LOGINTOKEN=your instance name";
$header = new SoapHeader('http://www.mywebservice.com/webservices/SoapService', 'SessionHeader', array('sessionId' => $token));
$client->__setSoapHeaders($header);
$client->login(array("wsUser" => array('entityId'=>'0','username'=>'my username','password'=>'my password')));
And the error I get:
**Fatal error**: Uncaught SoapFault exception: [ns1:InvalidSecurity] An error was discovered processing the <wsse:Security> header in C:\www\soap\index.php:12 Stack trace: #0 C:\www\soap\index.php(12): SoapClient->__call('login', Array) #1 C:\www\soap\index.php(12): SoapClient->login(Array) #2 {main} thrown in C:\www\soap\index.php on line 12
Update 3
So it looks like the "sessionId" is being sent as "key" with the token sent as "value".
*REQUEST*:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.mywebservice.com/webservices/SoapService">
<SOAP-ENV:Header>
<ns1:SessionHeader><item><key>sessionId</key><value>LOGINTOKEN=my token</value></item>
</ns1:SessionHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ns1:login><wsUser><entityId>0</entityId><password>my password</password><username>my username</username></wsUser></ns1:login></SOAP-ENV:Body></SOAP-ENV:Envelope>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否尝试过使用 SoapHeader 类来构造标头?像这样的东西会起作用吗?
这应该创建标头并将其添加到 SoapClient。使用 SoapClient 的每个后续调用都会设置该标头。至于具体的格式,我不会太担心。您的示例 XML 使用名为 urn 的命名空间的别名。 PHP 可能不会得到完全相同的别名,但它应该仍然可以工作。另外,我认为不需要在每个子元素中声明 xmlns。我认为子节点会自动继承 XML 中父节点的命名空间,但我对此并不能 100% 确定。最重要的是,只要在命名空间中声明了正确的 URL,即使 XML 与您的示例不完全匹配,也应该没问题。
您可以尝试的另一件事 - 您是否在 SoapClient 中打开了跟踪?这是可以传递给构造函数的参数之一,它使您能够查看 XML SOAP 请求和响应。如果使用 SoapHeader 类仍然不起作用,请尝试打开跟踪以查看正在发送和接收的内容。
Have you tried the SoapHeader class to construct your header? Would something like this work?
That should create the header and add it to the SoapClient. Every subsequent call using the SoapClient will then have that header set. As to the exact format, I wouldn't worry too much. You sample XML uses an alias for the namespace called urn. PHP probably won't arrive at exactly the same alias but it should still work. Also I don't think that declaring the xmlns in every child element is needed. I think that a child node automatically inherits the namespace of its parent in XML, but I'm not 100% certain on that. The bottom line is that as long as the right URL's are declared in the namespaces it should be fine even if the XML doesn't exactly match your example.
One other thing you could try-have you switched on tracing in the SoapClient? This is one of the parameters that can be passed to the constructor and it enables you to view the XML SOAP requests and responses. If it still doesn't work using the SoapHeader class try switching tracing on to see what's being sent and received.