【问题标题】:Why isn't my SOAP request working?为什么我的 SOAP 请求不起作用?
【发布时间】:2012-02-13 10:04:05
【问题描述】:

我正在尝试使用 PHP 发出 SOAP 请求。我的请求似乎与 SOAP 服务器文档中详述的请求相匹配(但方法略有不同),但我遇到了身份验证错误,好像没有包含标头一样。

文档的请求示例

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AuthHeader xmlns="http://novosolutions.com/">
      <SessionId>string</SessionId>
    </AuthHeader>
  </soap:Header>
  <soap:Body>
    <ViewTicket xmlns="http://novosolutions.com/">
      <Id>int</Id>
    </ViewTicket>
  </soap:Body>
</soap:Envelope>

我的 PHP 代码输出的请求:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://novosolutions.com/">
    <SOAP-ENV:Header>
        <ns1:AuthHeader>
            <SessionId>623</SessionId>
        </ns1:AuthHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:ViewTicket>
            <Id>1355110</Id>
        </ns1:ViewTicket>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我的 PHP 代码相当简单。我做错了吗?

$url = URL_BASE . URL_TICKET . '?WSDL';
$soapStruct = new SoapVar(array('SessionId' => SESSION_ID), SOAP_ENC_OBJECT);
$header = new SoapHeader('http://novosolutions.com/', 'AuthHeader', $soapStruct, false);

try {
    $client = new SoapClient($url, array('trace' => 1));
}
catch (SoapFault $exception) {
    echo 'Exception='.$exception;
}
$client->__setSoapHeaders(array($header));
var_dump($client);

$soapData = new SoapVar(array('Id' => 1355110), SOAP_ENC_OBJECT);
$result = $client->__soapCall('ViewTicket', array('parameters' => $soapData));

var_dump($result);
echo $client->__getLastRequest();

编辑: 通过使用 curl 测试请求,我将其范围缩小到 PHP 的 SoapClient 使用名称空间的变量这一事实。不被 SoapServer 接受,但被接受。现在我只需要弄清楚如何防止 SoapClient 使用变量。

【问题讨论】:

  • 您能找到解决方案吗?我得到了确切的问题。
  • 是的 - 我为会话 ID 添加了错误的 #。会话 ID 位于响应标头中,而不是响应正文中。要获取它,请使用 $responseHeaders = array(); $result = $client->__soapCall('Login', array('parameters' => $bodyVar), null, null, $responseHeaders); $sessionid = $responseHeaders['AuthHeader']->SessionId;

标签: php soap


【解决方案1】:

您只是尝试过这个吗?

error_reporting(E_ALL);
$client = new SoapClient($url,array('trace' => 1));
$client->__setSoapHeaders( new SoapHeader($url, 'SessionId', SESSION_ID) );
$result = $client->ViewTicket(array('Id'=>1355110));
var_dump($result);
echo '<hr>',str_replace('<','&lt;',$client->__getLastRequest());

它会产生什么样的错误信息?

【讨论】:

  • 感谢您的回复。没有 PHP 错误 - 结果相同(身份验证错误或会话已过期)。结果:codepad.org/EbQnxKO3
  • 我用soapUI软件尝试了同样的请求(在soapui.org免费获得),我得到了同样的结果(身份验证错误或会话已过期)......你确定它不需要凭据? (如用户/密码 HTTP 标头)?
  • 我几乎明白了——你知道如何防止 PHP 的 SoapClient 将变量用于命名空间吗?我需要 novosolutions.com"> 而不是
  • 您可以构建一个类扩展并使用 preg_replace 来完成这项工作,就像他们在 phpfreaks.com/forums/index.php?topic=326228.0 中解释的那样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 2017-01-17
  • 2021-12-20
相关资源
最近更新 更多