【问题标题】:PHP | SOAP 1.2 | How to set WS AddressingPHP |肥皂 1.2 |如何设置 WS 寻址
【发布时间】:2017-09-06 13:07:52
【问题描述】:

这里是WSDL ...

我在 PHP 中使用带有文档 HERE 的 SOAP 客户端 ...

肥皂电话

$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。

我不确定如何在 PHP 中使用 SOAP 客户端设置 WS 寻址 ...

【问题讨论】:

    标签: php soap soap-client wshttpbinding soap1.2


    【解决方案1】:

    以下代码对我有用。您可以启用 Ws-A 寻址并调用soap方法-

    $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
    

    【讨论】:

    • 我已经尝试过了,但它不适用于 bsestar getPassword。错误=无法到达目的地@Neeraj Yadav
    • 你能告诉我你在获取密码时遇到错误的 api。实际上我也为 BSE 实施了这个并且工作正常。 @Shashikant
    • $client = new SoapClient("bsestarmfdemo.bseindia.com/MFUploadService?Wsdl", array('soap_version' => SOAP_1_2,'trace' => 1,'exceptions'=> false )); $wsa_namespace = 'w3.org/2005/08/addressing'; $ACTION = 'bsestarmfdemo.bseindia.com/2016/01/IMFUploadService/getPassword'; $NS_ADDR = 'w3.org/2005/08/addressing'; $action = new SoapHeader($NS_ADDR, 'Action', $ACTION, true); $to = new SoapHeader($NS_ADDR, 'To', 'bsestarmfdemo.bseindia.com/MFUploadService/MFUploadService.svc/…', false);
    • $headerbody = array('Action' => $action,'To' => $to); $client->__setSoapHeaders($headerbody); $fcs = $client->__getFunctions(); $parameters=array('UserId'=>BSEUserId,'MemberId'=>BSEMemberId,'Password' => BSEPassword,'PassKey' => rand(10000,99999)); $result = $client->__soapCall('getPassword', array($parameters));
    • @sashi 在单个函数中同时使用上述注释并传递您的 bse 身份验证,例如 BSEUserId、BSEMemberId 和 BSEMemberId
    【解决方案2】:

    伙计,我完全感受到你的痛苦。我能够让它工作,但我认为这不是正确的方法,但它指向正确的方向。不过需要注意的是,您必须知道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);
    } 
    

    【讨论】:

      【解决方案3】:

      我的解决办法是

      1. 使用 SoapUi 发送请求
      2. 从 SoapUi 屏幕复制请求 http 日志(SoapUi 程序底部)
      3. 将该代码作为休耕方式放入 PHP 项目中

        $soap_request = '{从 SoapUi http 日志中复制该部分}';

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

      【讨论】:

        猜你喜欢
        • 2017-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多