【问题标题】:WSDL and SOAP: Return object with methodsWSDL 和 SOAP:使用方法返回对象
【发布时间】:2011-09-27 07:08:19
【问题描述】:

有没有办法用他的方法在肥皂中返回一个对象?如果我在 WSDL 中返回 xsd:struct,我只能获取对象的属性,但不能使用任何方法。

例如

class person
{
  var $name = "My name";
  public function getName()
  {
      return $this->name;
  }
}

所以在获取对象之后:

$client = new SoapClient();
$person = $client->getPerson();
echo $person->getName(); // Return "My Name";

谢谢。

【问题讨论】:

    标签: php soap wsdl


    【解决方案1】:

    SOAP 无法做到这一点。基本上,您的 PHP 类被映射到由 XML 模式定义的 XML 数据结构。此映射仅包括属性,不能包括可执行代码。 SOAP 旨在实现互操作性,自然不能在 PHP 和 Java 或 .NET 之间共享代码。在接收端,您的 XML 数据结构正在转换为客户端编程语言的数据结构(如果您使用 SoapClient,则为 PHP 类;如果您使用 C#,则为 C# 类)。由于 XML 数据结构仅携带属性信息,因此无法重建原始类的可执行部分。

    但是如果 SOAP 服务器和连接客户端都可以访问相同的代码库(这意味着相同的类),则有一件事情可以提供帮助。您可以使用classmap-选项在SoapClient 的构造函数中定义XML 类型和PHP 类之间的映射。这允许SoapClient 将传入的 XML 数据结构映射到真正的 PHP 类——因为服务器和客户端都可以访问相关的类定义。这允许您在SOAP 通信的接收方使用方法。

    class book {
        public $a = "a";
        public $b = "c";
        public function getName() {
            return $this->a.' '.$this->b;
        }
    }
    
    $options = array(
        'classmap' => array('book' => 'book')
    );
    $client = new SoapClient('path/to/wsdl', $options);
    $book    = $client->test();
    echo $book->getName();
    

    WSDL 可能看起来像(从SoapClient 测试之一复制并修改):

    <wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.nothing.com" targetNamespace="http://schemas.nothing.com">
        <wsdl:types>
            <xsd:schema targetNamespace="http://schemas.nothing.com">
                <xsd:complexType name="book">
                    <xsd:all>
                        <xsd:element name="a" type="xsd:string"/>
                        <xsd:element name="b" type="xsd:string"/>
                    </xsd:all>
                </xsd:complexType>
      </xsd:schema>
        </wsdl:types>
        <message name="testRequest">
        </message>
        <message name="testResponse">
            <part name="res" type="tns:book"/>
      </message>
        <portType name="testPortType">
            <operation name="test">
                <input message="tns:testRequest"/>
                <output message="tns:testResponse"/>
            </operation>
        </portType>
        <binding name="testBinding" type="tns:testPortType">
            <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
            <operation name="test">
                <soap:operation soapAction="http://localhost:81/test/interface.php?class=test/dotest" style="rpc"/>
                <input>
                    <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://schemas.nothing.com"/>
                </input>
                <output>
                    <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://schemas.nothing.com"/>
                </output>
            </operation>
        </binding>
        <service name="test">
            <port name="testPort" binding="tns:testBinding">
                <soap:address location="http://localhost:81/test/interface.php?class=test"/>
            </port>
        </service>
    </wsdl:definitions>
    

    如果您在 PHP 中使用 SOAPThe State of SOAP in PHP 可能会很有趣。

    【讨论】:

    • 哦,谢谢。您的解决方案很好,但不符合我的需求。我需要对公众隐藏这些方法。谢谢
    • 您想在客户端使用方法但又想隐藏它们?我认为这根本行不通......
    • 如果我在 SoapServer 中使用 setClass,我可以使用隐藏方法 :) 无论如何,我可以通过返回客户端肥皂对象来解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多