有没有人知道如何将属性添加到SoapVar对象?看起来它很简单,但我无法接受/工作。
我已经查看了PHP5文档以及以下stackoverflow问题:
http://www.php.net/manual/en/soapvar.soapvar.php,
stackoverflow问题: SoapVar/Param and nested, repeated elements in SOAP
我正在尝试添加类似此数组示例的属性,但使用复杂的SoapVar对象。
<?php
$amount['_'] = 25;
$amount['currencyId'] = 'GBP';
$encodded = new SoapVar($amount, SOAP_ENC_OBJECT);
?>
并且最终结果是
<amount currencyId="GBP">25</amount>
感谢。
答案 0 :(得分:1)
在 SOAP 元素中获取属性有点麻烦。他们实施的方式有点令人困惑。
首先要做的是将属性添加到 SoapServer
用来正确读取和响应 SOAP 请求的 wsdl 文件。
<xs:complexType name="encryptionContext">
<xs:simpleContent>
<xs:extension base="xs:string">
**<xs:attribute name="type" type="tns:encryptionType" />**
</xs:extension>
</xs:simpleContent>
</xs:complexType>
我们必须通过在选项中将其作为 SoapServer
传递来告诉 classmap
使用 php helper 类:
$soap_server = new \SoapServer($wsdl_file, array(
'cache_wsdl' => 1,
'trace' => true,
'classmap' => array('mediaCollection' => 'SoapMediaHelper')
));
我们在这里映射的是 SOAP 元素名称 mediaCollection
到我们的类之一 SoapMediaHelper
。我们现在可以返回一个 class
,而不是返回数组,在这种情况下,它被命名为 SoapMediaHelper
。该类可以有soap-element=>值对以及soap-attribute=>值对。
假设我们已经创建了一个处理 mediaCollection
的类,这会告诉 SoapServer
将一个名为 SoapMediaHelper
的类映射到它。这个类真的很简单:
class SoapMediaHelper
{
public function __construct(Array $properties = array())
{
foreach ($properties as $key => $value) {
$this->{$key} = $value;
}
}
}
必须填充此类的属性。这些属性应该是 tagname=>value 对以及我们想要添加到 mediaCollection
的属性的属性名称和值对。 SoapServer
会根据我们的 wsdl 文件找出哪个是哪个。
我们仍然需要填充这个对象,我们可以用另一个类来完成。
class SoapVarHelper
{
public function get($the_playlist, $playlist_id, $owned_by_user){
/* The SoapMediaHelper class is mapped to the mediaCollection wsdl.
* This is only needed to be able to set attributes on the XML nodes while using php's SoapServer
* */
$media_helper = new SoapMediaHelper($the_playlist);
/* For this type, the following xml attributes have to be set. (Not in the wsdl example above.) */
if($playlist_id === 'playlists'){
$media_helper->readOnly = false;
$media_helper->userContent = true;
$media_helper->renameable = false;
$media_helper->canDeleteItems = true;
}
if($owned_by_user){
$media_helper->readOnly = false;
$media_helper->userContent = false;
$media_helper->renameable = true;
$media_helper->canDeleteItems = true;
$media_helper->canReorderItems = true;
}
return new \SoapVar($media_helper, SOAP_ENC_OBJECT);
}
}
这个类应该用普通的标记名=>值对来调用。然后添加我们想要的属性。在这种情况下有条件。我们将 SoapMediaHelper
对象提供给 SoapVar
。 (我们之前告诉 SoapServer
这很好。)
现在我们需要做的最后一件事是,在我们的 mediaCollection
类中,使用助手 SoapVarHelper
返回一个 SoapMediaHelper
(我们告诉 SoapServer
更早)。
在我们的 mediaCollection
中,我们有一个函数 get_metadata_for_root
:
public function get_metadata_for_root($user_id, $index, $count){
$titles = array(
'slides' => 'Featured',
);
$media_metadata = array();
foreach($titles as $key => $title){
$playlist = array(
'id' => $key,
'title' => $title,
'img' => $this->_utils->get_url() . '/public/sonos/images/browse-icons/icon-default-legacy.png'
);
**$media_metadata[] = $this->_soap_var_helper->get($playlist, $key, false);**
}
$res = array(
'count' => count($media_metadata),
'index' => 0,
'total' => count($media_metadata),
'mediaCollection' => $media_metadata
);
}
对于每个 mediaCollection
结果,我们通过 soap_var_helper
传递它以确保不仅添加了 element=> 值对,而且还添加了我们想要的属性。
总结:
确保使用 wsdl 文件提供 SoapServer
,以便它知道元素和属性。
在 SoapServer
选项中添加 classmap
以告诉 SoapServer
当我们为它提供一个 SoapMediaHelper
对象而不是常规输入时是可以的。
在响应请求之前,在本例中为 mediaCollection
,通过 SoapMediaHelper
传递此响应。 SoapVarHelper
将所有属性=>值对映射为类属性,然后 SoapMediaHelper
将向其添加属性(也作为名称=>值对)。
SoapServer
会处理剩下的事情。