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);
?>
1 Content-Type. The Content-Type header for SOAP requests and responses specifies the MIME type for the message and is always text/xml. It may also specify the character encoding used for the XML body of the HTTP request or response. This follows the text/xml part of the header values.
The HTTP Content-Type of the SOAP request or SOAP response. The default is "text/xml".
php // Create Contact class class Contact { public function __construct($id, $name) { $this->id = $id; $this->name = $name; } } // Initialize WS with the WSDL $client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl"); // Create Contact obj $contact = new Contact(100, "John"); // Set request params $params = ...
SOAP uses XML to package the data passed to a method, or received as a response. SOAP itself is nothing more than a set of rules that define how to describe method calls and return values using XML syntax. XML merely describes data, without consideration for the way that the data is processed or presented.
Content-Type. The Content-Type header for a SOAP request and response defines the MIME type for the message and the character encoding (optional) used for the XML body of the request or response.
A SOAP message is an ordinary XML document containing the following elements: An Envelope element that identifies the XML document as a SOAP message. A Header element that contains header information. A Body element that contains call and response information. A Fault element containing errors and status information.
Java implementations of SOAP usually provide a specific binding for the JMS (Java Messaging System) protocol. The Content-Type header for a SOAP request and response defines the MIME type for the message and the character encoding (optional) used for the XML body of the request or response.
A SOAP message has no default encoding. The required SOAP Body element contains the actual SOAP message intended for the ultimate endpoint of the message. Immediate child elements of the SOAP Body element may be namespace-qualified.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With