2010-07-21 2 views
2

В Amazon AWS SQS WSDL (в https://sqs.us-east-1.amazonaws.com/doc/2009-02-01/QueueService.wsdl) перечислены несколько «портов» с разными «адресами» (в нижней части файла), которые определяют HTTP и HTTPS-адреса для службы.Как выбрать между различными портами в SOAP WSDL в PHP?

Использование объекта 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, которая не допускается с такой аутентификацией.

Если добавить (URL скопировать и вставить из файла WSDL) линии $sc->__setLocation('https://queue.amazonaws.com'); перед __soapCall, она работает нормально, но как я могу сказать, объект SoapClient использовать другой порт в WSDL, а не давая ему как статическую строку, если они изменят URL-адрес HTTPS по дороге?

ответ

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); 
    } 
} 

Если методы DO отличаются, вы можете переопределить метод __construct , и загрузите XML, и очистите или удалите любые ссылки на порт «http» вместо «https». Это выглядело бы больше и больше похоже на написание собственного soapclient, хотя :)