簡體   English   中英

如何將 SoapClient HTTP 內容類型設置為 application/soap+xml

[英]How to set SoapClient HTTP content type to application/soap+xml

我需要將內容類型從“text/xml;charset=utf-8”更改為“application/soap+xml;charset=utf-8”。

我正在使用 PHP 中默認存在的 SoapClient 類將請求從 PHP 發送到另一台服務器(Oracle 服務器)。 我正在使用 PHP v7.0.10。

根據 SoapClient 文檔,我應該將 options 數組中的 soap_version 設置為 SOAP_1_2 ,它會更改內容類型,但它不會這樣做。

SOAP 請求

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pub="http://xmlns.oracle.com/oxp/service/PublicReportService">
    <soap:Header/>
    <soap:Body>
        <pub:runReport>
            <pub:reportRequest>
                <pub:reportAbsolutePath>/Human Capital Management/Workforce Management/Human Resources Dashboard/Fusion User Information.xdo</pub:reportAbsolutePath>
                <pub:sizeOfDataChunkDownload>-1</pub:sizeOfDataChunkDownload>
            </pub:reportRequest>
        </pub:runReport>
    </soap:Body>
</soap:Envelope>

PHP代碼

$WSDL = "https://example.com/xmlpserver/services/ExternalReportWSSService?WSDL";

    $soap_options = array(
        'uri' => 'http://www.w3.org/2003/05/soap-envelope',
        'style' => SOAP_RPC,
        'use' => SOAP_ENCODED,
        'soap_version' => SOAP_1_2,
        'cache_wsdl' => WSDL_CACHE_NONE,
        'connection_timeout' => 30,
        'trace' => true,
        'encoding' => 'UTF-8',
        // 'exceptions' => true,
        'location' => $WSDL,
        'login' => '---',
        'password' => '---'
    );

    try {
        $soap_client = new SoapClient(NULL, $soap_options);
        $result = $soap_client->__doRequest($soap_request, $WSDL, "run", NULL);
        $clean_xml = str_ireplace(['SOAP-ENV:', 'SOAP:', 'env:'], '', $result);
        $xml = simplexml_load_string($clean_xml);
        var_dump($xml);
    } catch (Exception $e) {
        echo $e;
    }

最后一個請求標頭顯示

POST /xmlpserver/services/ExternalReportWSSService?WSDL HTTP/1.1
Host: example.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/7.0.10
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 510
Authorization: Basic ---

我嘗試通過多種方式設置內容類型,但每一種都失敗了

更新與解決方案

<?php

    $soap_request = <<<XML
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pub="http://xmlns.oracle.com/oxp/service/PublicReportService">
    <soap:Header/>
    <soap:Body>
        <pub:runReport>
            <pub:reportRequest>
                <pub:reportAbsolutePath>/Human Capital Management/Workforce Management/Human Resources Dashboard/Fusion User Information.xdo</pub:reportAbsolutePath>
                <pub:sizeOfDataChunkDownload>-1</pub:sizeOfDataChunkDownload>
            </pub:reportRequest>
        </pub:runReport>
    </soap:Body>
</soap:Envelope>
XML;

$WSDL = "https://example.com/xmlpserver/services/ExternalReportWSSService?WSDL";
    $user = "---";
    $password = "---";
$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_USERPWD,        $user.":".$password);
    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);
    var_dump($response);
?>

SoapClient手冊:

stream_context 選項是上下文的資源。

您可以在新創建的流上下文中設置 HTTP 標頭

$stream_context_opts = array(
    'http'=>array(
        'method'=>"POST",
        'header'=> "Content-Type: application/soap+xml; charset=utf-8\r\n"
    )
);

$soap_stream_context = stream_context_create($stream_context_opts);


 $soap_options = array(
    'uri' => 'http://www.w3.org/2003/05/soap-envelope',
    'style' => SOAP_RPC,
    'use' => SOAP_ENCODED,
    'soap_version' => SOAP_1_2,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'connection_timeout' => 30,
    'trace' => true,
    'encoding' => 'UTF-8',
    'stream_context' => $soap_stream_context,
    // 'exceptions' => true,
    'location' => $WSDL,
    'login' => '---',
    'password' => '---'
);

還有另一種方法可以通過創建子類並覆蓋 __doRequest 方法來做到這一點,

class MySoapClient extends SoapClient { 
    public function __construct($wsdl, $options = array()) {
        parent::__construct($wsdl, $options); 
    }
    public function __doRequest($request,$location,$action,$version,$one_way = 0) { 
        $handle = curl_init(); 
        curl_setopt($handle, CURLOPT_HEADER, false); 
        curl_setopt($handle, CURLOPT_URL, $location); 
        curl_setopt($handle, CURLOPT_FAILONERROR, true); 
        curl_setopt($handle, CURLOPT_HTTPHEADER, Array('Content-Type: application/soap+xml; charset=utf-8') ); 
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($handle, CURLOPT_POSTFIELDS, $request); 
        $response = curl_exec($handle); 
        if (empty($response)) { 
            throw new SoapFault('CURL error: '.curl_error($handle),curl_errno($handle)); 
        } 
        curl_close($handle); 
        return $response;
    } 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM