代码之家  ›  专栏  ›  技术社区  ›  stereoscott

对包含同名元素和complexType的WSDL使用PHP SoapClient classmap选项

  •  11
  • stereoscott  · 技术社区  · 15 年前

    我遇到了几个不同的WSDL文件,它们包含一个元素和一个同名的complexType。例如, http://soap.search.msn.com/webservices.asmx?wsdl 有两个名为“SearchResponse”的实体:

    在这个场景中,我不知道如何使用SoapClient()“classmaps”选项将这些实体正确地映射到PHP类。

    classmap选项可用于映射 选项必须是具有WSDL的数组 类型作为PHP类的键和名称

    不幸的是,由于有两种WSDL类型具有相同的键('SearchResponse'),所以我不知道如何区分这两个SearchResponse实体并将它们分配给相应的PHP类。

    例如,下面是示例WSDL的相关片段:

    <xsd:complexType name="SearchResponse">
        <xsd:sequence>
            <xsd:element minOccurs="1" maxOccurs="1" name="Responses" type="tns:ArrayOfSourceResponseResponses"/>
        </xsd:sequence>
    </xsd:complexType>
    
    <xsd:element name="SearchResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element minOccurs="1" maxOccurs="1" name="Response" type="tns:SearchResponse"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    

    这是PHP,显然

    <?php $server = new SoapClient("http://soap.search.msn.com/webservices.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MySearchResponseElement', 'SearchResponse' => 'MySearchResponseComplexType'))); ?>
    

    在搜索解决方案时,我发现javaweb服务通过允许您为“Element”或“ComplexType”实体指定自定义后缀来处理这个问题。

    http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp149350

    所以,现在我觉得用PHP的SoapClient是没有办法做到的,但是我很好奇是否有人能提供任何建议。FWIW,我无法编辑远程WDSL。

    有什么想法吗???

    1 回复  |  直到 15 年前
        1
  •  7
  •   Kayla Rose    15 年前

    <?php
    //Assuming SearchResponse<complexType> contains SearchReponse<element> which contains and Array of SourceResponses
    //You could try abstracting the nested Hierarchy like so:
    class MY_SearchResponse
    {
       protected $Responses;
       protected $Response;
    
       /**
        * This should return the nested SearchReponse<element> as a MY_SearchRepsonse or NULL
        **/
       public function get_search_response()
       {
          if($this->Response && isset($this->Response))
          {
             return $this->Response; //This should also be a MY_SearchResponse
          }
          return NULL;
       }
    
       /**
        * This should return an array of SourceList Responses or NULL
        **/
       public function get_source_responses()
       {
          //If this is an instance of the top SearchResponse<complexType>, try to get the SearchResponse<element> and it's source responses
          if($this->get_search_response() && isset($this->get_search_response()->get_source_responses()))
          {
             return $this->get_search_response()->get_source_responses();
          }
          //We are already the nested SearchReponse<element> just go directly at the Responses
          elseif($this->Responses && is_array($this->Responses)
          {
             return $this->Responses;
          }
          return NULL;
       }
    }
    
    class MY_SourceResponse
    {
      //whatever properties SourceResponses have
    }
    
    $client = new SoapClient("http:/theurl.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MY_SearchResponse', 'SourceResponse' => 'MY_SourceResponse')));