如何在php中设置mustUnderstand属性soap?

时间:2015-03-10 15:21:51

标签: php xml soap wsdl

我已尝试将 mustUnderstand 属性设置为我的xml标头,但无法对其进行排序,这是我的代码段,

$actionurl = array('Action'=>'www.example.com');
$headers = new SoapHeader('NAMESPACE','Action',$actionurl,true);
$client->__setSoapHeaders($headers);
$d = $client->__soapCall('MethodName',array($params));

我的请求xml,在设置属性后要匹配和我想要的

<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">www.example.com</Action>

所以我对这个命名空间&#39;感到困惑。在soapheader方法中的第一个参数。它是什么,为什么我们使用相同的?提及this link并且它根本没有用。任何人都可以帮我解决xml请求格式吗?

1 个答案:

答案 0 :(得分:3)

首先,如果您想将您创建的代码与您所拥有的XML进行比较,那么您需要有一些东西可以查看 SoapClient 将创建的XML

您可以通过模拟 SoapClient

来实现此目的
/**
 * Class MockSoapClient
 */
class MockSoapClient extends SoapClient
{
    /**
     * @var string|null
     */
    private $lastRequest;

    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $config = ['input-xml' => 1, 'indent' => 1, 'wrap' => 0, 'indent-attributes' => 1];

        $this->lastRequest = tidy_repair_string($request, $config);

        return "";
    }

    /**
     * @return string|null
     */
    public function getLastRequest()
    {
        return $this->lastRequest;
    }
}

您可以使用新的 MockSoapClient 替换正常的 SoapClient ,该 MockSoapClient 能够显示已创建 SoapClient 的请求。

假冒你的请求:

$client = new MockSoapClient(null, array('location' => "http://localhost/soap.php",
                                         'uri'      => "http://test-uri/"));

$actionurl = array('Action' => 'www.example.com');

$header = new SoapHeader('NAMESPACE', 'Action', $actionurl, true);

$client->__soapCall("echoVoid", array(), null, $header);

并查看请求的外观:

echo $client->getLastRequest();

这里输出:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://test-uri/"
                   xmlns:ns2="NAMESPACE"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <ns2:Action SOAP-ENV:mustUnderstand="1">
      <item>
        <key>Action</key>
        <value>www.example.com</value>
      </item>
    </ns2:Action>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:echoVoid />
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这里有趣的部分是肥皂标题:

<SOAP-ENV:Header>
  <ns2:Action SOAP-ENV:mustUnderstand="1">
    <item>
      <key>Action</key>
      <value>www.example.com</value>
    </item>
  </ns2:Action>
</SOAP-ENV:Header>

此处&#34; ns2:&#34;是&#34; NAMESPACE&#34;的前缀命名空间是错误的。在您的示例中:

<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">www.example.com</Action>

<action>元素的名称空间为&#34; http://schemas.microsoft.com/ws/2005/05/addressing/none&#34;。所以&#34; NAMESPACE&#34;必须替换为&#34; http://schemas.microsoft.com/ws/2005/05/addressing/none&#34;。

mustUnderstand属性位于正确的命名空间中,所以这很好。这并不奇怪,因为它是标准Soap命名空间之一,因此这些是预先定义的,您不必在此处小心谨慎。只有它们的前缀不同,但只要不同的前缀引用相同的命名空间,就没有区别。

第三点错误是<action>元素的内容,你只需要一个字符串,而不是<item> - <key> / <value>构造是因为你有阵列。让我们再试一次:

$namespace = 'http://schemas.microsoft.com/ws/2005/05/addressing/none';
$actionurl = 'www.example.com';

$header = new SoapHeader($namespace, 'Action', $actionurl, true);

现在输出看起来非常正确:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://test-uri/"
                   xmlns:ns2="http://schemas.microsoft.com/ws/2005/05/addressing/none"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <ns2:Action SOAP-ENV:mustUnderstand="1">www.example.com</ns2:Action>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:echoVoid />
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我希望这个答案可以帮助您理解XML namespaces的一些基础知识,以及如何通过检查请求XML来更轻松地调试您在此创建的soap请求。