简体   繁体   中英

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

I need to change the content type from "text/xml; charset=utf-8" to "application/soap+xml; charset=utf-8".

I'm sending a request from PHP to another server (Oracle server) using SoapClient class that exist by default in PHP. I'm using PHP v7.0.10.

As per SoapClient documentation I should just set the soap_version inside the options array to SOAP_1_2 and it will change the content type but it doesn't do that.

SOAP Request

<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 Code

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

Last request header shows

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

I've tried to set the content type by so many ways and every one of them failed

Update & Solution

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

From SoapClient manual:

The stream_context option is a resource for context.

You can set HTTP headers in your newly created stream context

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

There is another way to do this by making a child class and override __doRequest method,

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM