将属性添加到 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 使用php 帮助类,方法是将其作为classmap 传递到选项中:
$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=>值对。
假设我们已经创建了一个处理mediaCollections 的类,这告诉SoapServer 将一个名为SoapMediaHelper 的类映射到它。这个类真的很简单:
class SoapMediaHelper
{
public function __construct(Array $properties = array())
{
foreach ($properties as $key => $value) {
$this->{$key} = $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,以确保不仅添加了元素=>值对,而且还添加了我们想要的属性。
总结:
-
确保使用 wsdl 文件提供 SoapServer,以便它知道元素和属性。
-
在SoapServer 选项中添加classmap 以告诉SoapServer,当我们向它提供SoapMediaHelper 对象而不是常规输入时很好。
-
在响应mediaCollection 的请求之前,请通过SoapMediaHelper 传递此响应。 SoapVarHelper 会将所有属性=>值对映射为类属性,然后SoapMediaHelper 将向其添加属性(也作为名称=>值对)。
-
SoapServer 将负责其余的工作。