[英]How to set content type to 'application/soap+xml; charset=utf-8' in PHP while SOAP request
[英]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.