[英]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".我需要将内容类型从“text/xml;charset=utf-8”更改为“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.我正在使用 PHP 中默认存在的 SoapClient 类将请求从 PHP 发送到另一台服务器(Oracle 服务器)。 I'm using PHP v7.0.10.
我正在使用 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.根据 SoapClient 文档,我应该将 options 数组中的 soap_version 设置为 SOAP_1_2 ,它会更改内容类型,但它不会这样做。
SOAP Request 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 Code 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;
}
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:从SoapClient手册:
The stream_context option is a resource for context.
stream_context 选项是上下文的资源。
You can set HTTP headers in your newly created 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' => '---'
);
There is another way to do this by making a child class and override __doRequest method,还有另一种方法可以通过创建子类并覆盖 __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.