我需要将内容类型从“ 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);
?>
答案 0 :(得分:1)
摘自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;
}
}