php SoapVar没有设置属性

时间:2014-07-21 17:16:54

标签: php soap

我试图在soap请求中添加一些属性。对PHP.net(http://php.net/manual/en/soapvar.soapvar.php)以及herehere的评价最高的评论都说同样的事情:

$param = array(
    "_" => 'value',
    'attrName' => 'attributeName'
);
$p = new SoapVar($param, SOAP_ENC_OBJECT);

应该返回

<param attrName="attributeName">value</param>

哪个会很棒,除非我运行那段代码,我得到这个XML:

<param>
    <_>value</_>
    <attrName>attributeName</attrName>
</param>

这显然是错误的。当然,我不是世界上唯一遇到这个问题的人吗?自2011年以来,关于这一小部分功能的文档是否发生了变化?

3 个答案:

答案 0 :(得分:2)

是的,你并不是唯一一个遇到这个问题的人 - 我看过无数的帖子,人们声称传递给SoapVar的数据使用SOAP_ENC_OBJECT解决了这个问题,而其他人则在同一帖子上声称不这样做。文档上的原因并不清楚(除了我去年在php.net的评论部分发表的文章)。

面对同样的问题,我已经阅读了PHP SOAP扩展的来源。基本上你使用的语法绝对正确:

$param = array(
    "_" => 'value',
    'attrName' => 'attributeName'
);
$p = new SoapVar($param, SOAP_ENC_OBJECT);

文档没有说明:这种语法可能会产生两种不同的结果(实际上甚至更多:PHP SOAP可能以八种不同的方式表达它)。正如您可能看到上面的代码含糊不清:上面的代码中说'attrName'是属性而不是元素?没有。上面的代码没有足够的信息供SoapClient决定'attrName'是什么,所以它默认为“一个元素”。

SoapClient可以以两种模式运行:非WSDL和WSDL。在以前的模式中,您永远不会得到您想要的结果:SoapClient依赖于类型信息以将数组元素转换为属性。由于非WSDL模式中不存在类型信息,SoapClient将提供的数组表示为元素集 - 正是您所获得的。在WSDL模式中,存在类型信息,因此SoapClient知道元素和属性名称,并且可以将它们与数组索引匹配。因此,如果您需要属性,则必须在WSDL模式下使用SoapClient。

基本上为了达到你想要的效果,你需要在文档/文字模式下使用&lt; xsd:attribute name =“attrName”type =“xsd:string”/&gt;在&lt; xsd:schema&gt;的相应部分中块。

有些人声称成功使用属性的数组和其他人说“它不起作用”的原因仅在于它们的设置:有些人要使用WSDL文件,有些人只是想尝试新的SoapClient(null,阵列(...)); (这当然没有达到他们的期望)

答案 1 :(得分:0)

目前我正在使用DOMDocument对象来创建节点。希望有一种更简单的方法,但为了回答这个问题并提供一个解决方法,这里有:

$dom = new DOMDocument("1.0", "utf-8");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$param = $dom->createElement('param');
$paramAttr = $dom->createAttribute('attrName');
$paramAttr->value = "attributeName";
$param->value = "value";
$param->appendChild($paramAttr);
$dom->appendChild($param);
$soap->param = new SoapVar($dom->saveXML($dom->documentElement), XSD_ANYXML);

所以不太理想。另一种方法是自己编写XML:

$soap->param = new SoapVar("<param attrName='attributeName'>value</param>", XSD_ANYXML);

我不喜欢任何一种方式,但是当你有一个截止日期时,你会选择合适的方式。

答案 2 :(得分:0)

我知道这是一个老问题,但我想为其他任何偶然发现这篇文章的人提供答案。我遇到了与mounty相同的问题,并且能够使用不需要var mongoose = require('mongoose'); var db = mongoose.createConnection(..); db.model('Venue', new Schema(..)); var Ticket = db.model('Ticket', new Schema(..)); var Venue = db.model('Venue'); 的解决方案来解决它。我无法使XSD_ANYXML方法工作SoapVar,但能够使用与类属性相同的键来使其工作。例如,使用以下代码:

array

在使用wsdl2phpgenerator库从包含需要属性的数据类型的WSDL生成PHP类并看到正在使用此模式之后,我才能解决这个问题。