繁体   English   中英

php SoapVar没有设置属性

[英]php SoapVar not setting attributes

我正在尝试为soap请求添加一些属性。 上评分最高PHP.net评论( http://php.net/manual/en/soapvar.soapvar.php ),并在这里这里的SO都说着同样的事情:

$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年以来,关于这一点功能的文档是否发生了变化?

是的,你不是唯一一个遇到这个问题的人 - 我看到过无数的帖子,人们声称使用SOAP_ENC_OBJECT传递给SoapVar的数组解决了这个问题,而其他人则在同一帖子上声称没有。 并且文档不清楚的原因(除了我的帖子年前在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。

基本上为了实现您想要的目标,您需要在<xsd:schema>块的相应部分中使用<xsd:attribute name =“attrName”type =“xsd:string”/>在文档/文字模式下使用WSDL文件。

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

目前我正在使用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);

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

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

class MyParam {
  public $_;
  public $attrName;

  public function __construct($paramValue, $attrValue)
  {
    $this->_ = $paramValue;
    $this->attrName = $attrValue;
  }
}

$soap->param = new MyParam("value", "attributeName");

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM