使用代理时,PHP SoapClient无法通过HTTPS访问Web服务

时间:2014-01-31 13:13:36

标签: php soap https proxy wsdl

在PHP(版本5.3.10)中使用SoapClient我遇到了一个我无法找到解决方案的问题。

用于联系Web服务的HTTPS和代理的组合给了我一些真正的痛苦。有没有办法让这个工作?

给出以下设置:

$WSDL = 'https://(...).php?wsdl';

$params =  array(
    'proxy_host' => 'localhost',
    'proxy_port' => 3128
);

这有效:

$client = new SoapClient($WSDL);
var_dump($client->__getFunctions());
var_dump($client->__call('someFunc', array()));

这会在某些时候出错:

$client = new SoapClient($WSDL, $params);
var_dump($client->__getFunctions());
var_dump($client->__call('someFunc', array()));

我尝试了一些曲折和黑客试图缩小问题范围:

  • $WSDL设置为基于HTTP的服务时,两种方法都有效。
  • 当本地下载基于HTTPS的服务的WSDL并且$WSDL设置为此时,失败的方法会生成函数,但在尝试调用函数时会失败。

从使用HTTPS-url初始化客户端到启用wsdl和代理,PHP退出时出现以下错误:

Fatal error: Uncaught SoapFault exception:
 [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://(...).php?wsdl' :
  failed to load external entity https://(...).php?wsdl

使用本地存储的WSDL定义文件初始化客户端时,PHP退出时出现以下错误:

Fatal error: Uncaught SoapFault exception:
 [HTTP] Bad Request in test.php:19
 Stack trace: #0 [internal function]: SoapClient->__doRequest

从我的角度来看,这看起来像是一个PHP错误,但希望有一种解决方法 我是否必须去NuSoap等图书馆? 这是在另一个版本的PHP中修复的吗? 我错过了什么吗?

3 个答案:

答案 0 :(得分:1)

在localhost上使用Fiddler2代理时出现此问题。必须导出Fiddler的根证书并明确设置cafile这样的选项

$client = new SoapClient($url, [
        'proxy_host' => 'localhost', 
        'proxy_port' => 8888,
        'stream_context' => stream_context_create([ 
            'ssl' => [ 'cafile' => 'C:\path\to\FiddlerRoot.pem' ] ])
        ]);

...用于https访问要捕获的服务。

FiddlerRoot.pem使用certmgr.msc DO_NOT_TRUST_FiddlerRoot-CE商店中的Personal条目Base-64 encoded X.509 (.CER)导出,<input type="text" name="optionalField[]" ng-model="optionalField[0]"> <input type="text" name="optionalField[]" ng-model="optionalField[1]"> <input type="text" name="optionalField[]" ng-model="optionalField[2]"> 选项。

答案 1 :(得分:0)

我不得不使用wsdl文件的本地副本,我正在使用这个选项:

  array(
    'trace' => 1,
    'exceptions' => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'proxy_host' => self::PROXY_HOST,
    'proxy_port' => self::PROXY_PORT,
    'proxy_login' => self::PROXY_USER,
    'proxy_password' => self::PROXY_PASS,
  )

也许选项tracecache_wsdl可以为您提供帮助。

答案 2 :(得分:0)

我在防火墙后面。我必须设置代理和端口才能使我的代码正常工作。

$client = new SoapClient($wsdl, [
        "trace" => 1,
        "exceptions" => 1,
        "proxy_host" => "PROXY_HOST_STRING",
        "proxy_port" => PROXY_PORT_NUMBER
    ]);