4

有没有人知道如何向 SoapVar 对象添加属性?看起来这很简单,但我无法接受/工作。

我查看了 PHP 文档和以下 stackoverflow 问题:

关于 SoapVar 的文档

stackoverflow 问题: SoapVar/Param 和 SOAP 中的嵌套重复元素

我正在尝试添加一个类似这个数组示例的属性,但使用复杂的 SoapVar 对象。

<?php
 $amount['_'] = 25;
 $amount['currencyId'] = 'GBP';
 $encodded = new SoapVar($amount, SOAP_ENC_OBJECT);

?>

最终结果是伤口

<amount currencyId="GBP">25</amount> 

谢谢。

4

1 回答 1

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通过在选项中传递它来告诉使用 php helper 类classmap

$soap_server = new \SoapServer($wsdl_file, array(
    'cache_wsdl' => 1,
    'trace' => true,
    'classmap' => array('mediaCollection' => 'SoapMediaHelper')
));

我们在这里映射的是 SOAP 元素名称mediaCollection到我们的类之一,SoapMediaHelper. 我们现在可以返回 a class,而不是返回数组,在这种情况下,它被命名为SoapMediaHelper。该类可以有soap-element=>value 对以及soap-attribute=>value 对。

假设我们已经创建了一个处理mediaCollections 的类,这告诉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器返回 a 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=>value 对,而且还添加了我们想要的属性。

总结:

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

  2. SoapServer选项中添加classmap是为了告诉SoapServer我们当我们给它一个SoapMediaHelper对象而不是常规输入时它很好。

  3. 在响应请求之前,在这种情况下,mediaCollection将响应传递给SoapMediaHelper. SoapVarHelper会将所有属性=> 值对映射为类属性,然后将SoapMediaHelper属性(也作为名称=> 值对)添加到它。

  4. SoapServer会照顾其余的。

于 2021-04-18T12:22:50.743 回答