【问题标题】:How to choose between different Ports in a SOAP WSDL in PHP?如何在 PHP 中的 SOAP WSDL 中的不同端口之间进行选择?
【发布时间】:2010-08-27 17:28:59
【问题描述】:

Amazon AWS SQS WSDL(https://sqs.us-east-1.amazonaws.com/doc/2009-02-01/QueueService.wsdl)列出了具有不同“地址”(靠近文件底部)的多个“端口”,它们指定了服务的 HTTP 和 HTTPS 地址。

使用 PHP SOAP 对象:

$aws_ns = 'http://security.amazonaws.com/doc/2007-01-01/';
$sc = new SoapClient('https://sqs.us-east-1.amazonaws.com/doc/2009-02-01/QueueService.wsdl');
$sc->__setSoapHeaders(new SoapHeader($aws_ns, 'AWSAccessKeyId', 'MyAccessKey'));
$action = "ListQueues";
$ts = date('c');
$hash = base64_encode(hash_hmac('sha1', $action.$ts, 'MyPrivateKey', true));
try {
  $rs = $sc->__soapCall($action, array(), NULL, array(
    new SoapHeader($aws_ns, 'Signature', $hash),
    new SoapHeader($aws_ns, 'Timestamp', $ts)
  ));
} catch (SoapFault $f) {
  echo "ERROR: ".$f->faultcode."-".$f->faultstring."\n";
}

运行该代码会给出“错误:aws:Client.RequiresSSL-SSL 连接需要向后兼容的 SOAP 身份验证。”;它使用第一个“端口”(HTTP 端口)联系 AWS 服务,这种身份验证不允许这样做。

如果我在__soapCall 之前添加一个$sc->__setLocation('https://queue.amazonaws.com');(从WSDL 文件复制和粘贴的URL)行,它可以正常工作,但是我如何告诉SoapClient 对象使用WSDL 中的另一个端口,而不是而不是将其作为静态字符串提供,以防他们在路上更改 HTTPS URL?

【问题讨论】:

    标签: php soap amazon-sqs


    【解决方案1】:

    据我所知,没有简单的方法可以告诉 SoapClient 使用另一个。如果只需要将http 更改为https,并且所有其他条件都相同,则可以使用自己的类覆盖某些方法:

    class HttpsPortSoapClient extends Soapclient {
      function __doRequest($request,$location,$action,$version,$one_way = 0 ){
        $locationparts = parse_url($location);
        if(isset($locationparts['scheme']) && $locationparts['scheme'] == 'http'){
          if(function_exists('http_build_url')){
            $location = http_build_url($locationparts,array('scheme'=>'https'));
          } else {
            //the long way around:
            $location = 'https://';
            if(isset($locationparts['user'])){
              $location .= $locationparts['user'];
              if(isset($locationparts['pass']))$location .= ':'.$locationparts['pass'];
              $location .= '@';
            }
            if(isset($locationparts['host']))  $location .= $locationparts['host'];
            if(isset($locationparts['port']))  $location .= ':'.$locationparts['port'];
            if(isset($locationparts['path']))  $location .= $locationparts['path'];
            if(isset($locationparts['query'])) $location .= '?'.$locationparts['query'];
          }
        }
        return parent::__doRequest($request,$location,$action,$version,$one_way);
      }
    }
    

    如果方法确实不同,您可能需要覆盖 __construct 方法,加载 XML,清理或删除对“http”端口而不是“https”端口的任何引用。不过,它看起来越来越像编写自己的soapclient了:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多