gpt4 book ai didi

php - 如何将 SoapClient HTTP 内容类型设置为 application/soap+xml

转载 作者:行者123 更新时间:2023-12-03 11:22:50 26 4
gpt4 key购买 nike

我需要将内容类型从“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;
}

最后一个请求 header 显示
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手动的:

The stream_context option is a resource for context.



您可以在新创建的流上下文中设置 HTTP header
$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;
}
}

关于php - 如何将 SoapClient HTTP 内容类型设置为 application/soap+xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52845999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com