PHP | SOAP 1.2 | Как установить WS-адресацию

Вот WSDL...

Я использую клиент SOAP в PHP с документацией ЗДЕСЬ...

Мыло вызов

$wsdl = 'https://api.krollcorp.com/EBusinessTest/Kroll.Dealer.EBusiness.svc/Docs?singleWsdl';

try {
    $client = new SoapClient($wsdl, array('soap_version' => SOAP_1_2, 'trace' => 1));
    // $result = $client->SubmitPurchaseOrder();
    $result = $client->__soapCall("SubmitPurchaseOrder", array());
} catch (SoapFault $e) {
    printf("\nERROR: %s\n", $e->getMessage());
}

$requestHeaders = $client->__getLastRequestHeaders();
$request = $client->__getLastRequest();
$responseHeaders = $client->__getLastResponseHeaders();
printf("\nRequest Headers -----\n");
print_r($requestHeaders);
printf("\nRequest -----\n");
print_r($request);
printf("\nResponse Headers -----\n");
print_r($responseHeaders);
printf("\nEND\n");

Выход

ERROR: The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/IEBusinessService/SubmitPurchaseOrder'.

Request Headers -----
POST /EBusinessTest/Kroll.Dealer.EBusiness.svc HTTP/1.1
Host: api.krollcorp.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.19
Content-Type: application/soap+xml; charset=utf-8; action="http://tempuri.org/IEBusinessService/SubmitPurchaseOrder"
Content-Length: 200


Request -----
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/"><env:Body><ns1:SubmitPurchaseOrder/></env:Body></env:Envelope>

Response Headers -----
HTTP/1.1 500 Internal Server Error
Content-Length: 637
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 06 Sep 2017 12:42:57 GMT

END

попытки

Я новичок в использовании SOAP API.

Я считаю, что это не удается, потому что SOAP 1.2 использует WsHttpBinding вместо BasicHttpBinding.

Я не уверен, как установить адресацию WS с клиентом SOAP в PHP...

2 ответа

Ниже код работает для меня. Вы можете включить адресацию Ws-A и вызвать метод мыла-

$client = new SoapClient("http://www.xyz.Services?Wsdl", array('soap_version'   => SOAP_1_2,'trace' => 1,'exceptions'=> false
    ));
    $wsa_namespace = 'http://www.w3.org/2005/08/addressing';
    $ACTION_ISSUE = 'http://www.xyx/getPassword';// Url With method name
    $NS_ADDR = 'http://www.w3.org/2005/08/addressing';
    $action = new SoapHeader($NS_ADDR, 'Action', $ACTION_ISSUE, true);

    $to = new SoapHeader($NS_ADDR, 'To', 'http://www.xyx.svc/Basic', false);
    $headerbody = array('Action' => $action,'To' => $to);
    $client->__setSoapHeaders($headerbody);


    //$fcs = $client->__getFunctions();
    //pre($client->__getLastRequest());
//pre($fcs);

$parameters=array('UserId'=>'12345678','MemberId'=>'123456','Password' => '123456','PassKey' => 'abcdef1234');
;
$result = $client->__soapCall('getPassword', array($parameters));//getPassword method name
print_r(htmlspecialchars($client->__getLastRequest()));// view your request in xml code

print_r($client->__getLastRequest());die; //Get Last Request

print_r($result);die; //print response

Мое решение

  1. Отправить запрос с помощью SoapUi
  2. Скопируйте http-журнал запроса с экрана SoapUi (нижняя часть программы SoapUi)
  3. Вставьте этот код в проект PHP как фальшивый

    $ soap_request = '{скопировать эту часть из протокола HTTP SoapUi}';

        $WSDL = "**wsdl adres**";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER,         false);
        curl_setopt($ch, CURLOPT_URL,            $WSDL);
        curl_setopt($ch, CURLOPT_FAILONERROR,    true);
        curl_setopt($ch, CURLOPT_HTTPHEADER,     Array(
            'Content-Type: application/soap+xml; charset=utf-8',
            'SOAPAction: "run"',
            'Accept: text/xml',
            'Cache-Control: no-cache',
            'Pragma: no-cache',
            'Content-length: '. strlen($soap_request),
            'User-Agent: PHP-SOAP/7.0.10',
        ));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT,        30);
        curl_setopt($ch, CURLOPT_POSTFIELDS,     $soap_request);
        $response = curl_exec($ch);
        if (empty($response)) {
            throw new SoapFault('CURL error: '.curl_error($ch), curl_errno($ch));
        }
        curl_close($ch);
    

Чувак, я полностью чувствую твою боль. Я смог заставить это работать, но я не думаю, что это правильный путь, но он указывает в правильном направлении. Тем не менее, вы должны знать, какое пространство имен soap_client собирается назначить адресации. Лучший способ - просто захватить XML-запрос и посмотреть, какое пространство имен является присоединением к адресации, а затем передать его. Ниже приведен мой код со значением по умолчанию ns2 для пространства имен, но вы не можете рассчитывать на него в качестве своего пример. Удачи!

private function generateWSAddressingHeader($action,$to,$replyto,$message_id=false,$ns='ns2')
{
    $message_id = ($message_id) ? $message_id : $this->_uniqueId(true);
    $soap_header = <<<SOAP
        <{$ns}:Action env:mustUnderstand="0">{$action}</{$ns}:Action>
        <{$ns}:MessageID>urn:uuid:{$message_id}</{$ns}:MessageID>
        <{$ns}:ReplyTo>
          <{$ns}:Address>{$replyto}</{$ns}:Address>
        </{$ns}:ReplyTo>
        <{$ns}:To env:mustUnderstand="0">$to</{$ns}:To>
SOAP;
    return new \SoapHeader('http://www.w3.org/2005/08/addressing','Addressing',new \SoapVar($soap_header, XSD_ANYXML),true);
} 
Другие вопросы по тегам