PHP SoapVar对象属性?

时间:2011-08-28 20:56:58

标签: php soap

有没有人知道如何将属性添加到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> 

感谢。

1 个答案:

答案 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=> 值对,而且还添加了我们想要的属性。

总结:

  1. 确保使用 wsdl 文件提供 SoapServer,以便它知道元素和属性。

  2. SoapServer 选项中添加 classmap 以告诉 SoapServer 当我们为它提供一个 SoapMediaHelper 对象而不是常规输入时是可以的。

  3. 在响应请求之前,在本例中为 mediaCollection,通过 SoapMediaHelper 传递此响应。 SoapVarHelper 将所有属性=>值对映射为类属性,然后 SoapMediaHelper 将向其添加属性(也作为名称=>值对)。

  4. SoapServer 会处理剩下的事情。