短版本
我想扩展SoapClient
,以便它在访问WSDL:时在内部执行此操作
curl -L -E /location/of/cert.pem -c /tmp/location/of/cookie.jar https://web-service-provider/servicename?wsdl
长版本
我收到一个类似于以下内容的SOAP请求:
$serviceUrl = 'https://service-url';
$wsdl = $serviceUrl . '?wsdl';
$proxyServiceUrl = 'http://localhost/myproxy.php?url=$serviceUrl';
$proxyWsdl = 'http://localhost/myproxy.php?url=$wsdl';
$options = array(
'cache_wsdl' => WSDL_CACHE_NONE,
'encoding' => 'utf-8',
'soap_version' => SOAP_1_1,
'exceptions' => true,
'trace' => true,
'location' => $proxyServiceUrl
);
$client = new SoapClient($proxyWsdl, $options);
$params = array( /* */ );
$client->someOperation($params);
正如您所看到的,除了代理位之外,一切都非常标准。
代理原因
我编写代理是为了满足web服务提供商的一个要求,即包括WSDL在内的所有端点都要通过一个名为siteminder的身份验证系统进行处理。
代理的功能非常直接,如果用linux命令行curl编写,它将是这样的:
curl -L -E /location/of/cert.pem -c /tmp/location/of/cookie.jar https://web-service-provider/servicename?wsdl
准确地说:
* Follow all redirections
* specify location of .pem file (and password)
* specify location of cookie jar
这一切都很好:)
但是最近服务提供商决定更改其WSDL。
它现在导入模式文件(.xsd
),这并没有那么糟糕,只是它是相对于WSDL的。
相对于WSDL文件意味着SoapClient
解析器现在从代理的位置查找模式文件。错误,找不到!
关于这个问题的更多细节:
php SoapClient在传递带有相对路径模式的wsdl时失败
所以我的问题是:
我如何重写SoapClient
(当然是通过扩展它),仍然通过siteminder身份验证,但不必通过额外的代理?
我最初的想法是,我必须以某种方式重写URI访问器函数(如果存在的话),但如果没有这方面的文档,我不确定从哪里开始。
或者,我可能不得不以某种方式破解SoapServer
。
如果能得到任何帮助,包括指向SoapClient
内部任何文档的指针,我将不胜感激。
如果只是提供.pem文件的问题,您是否研究过SoapClient构造函数的local_cert
选项?然后,该客户端对象应该保留为会话设置的任何cookie。如果您也需要在会话中保存cookie,您可以始终从响应中读取它们(使用__getLastResponseHeaders
),然后使用__setCookie
下次再次设置它们。
或者,您可以让代理将相对路径替换为绝对路径。毕竟,wsdl本身就是一个XML文档。
或者,您可以将代理变成一个实际的代理,并使用proxy_host、proxy_port、proxy_login和proxy_password选项。
这个令人挠头、揪头发的问题的答案可以在这里找到:
http://rabaix.net/en/articles/2008/03/13/using-soap-php-with-ntlm-authentication.
感谢php soap邮件列表上的Jeffery Fernandez指出了这一点。