2011-10-13 85 views
9

我试图创建在PHP中使用本地SoapServer的类简单的SOAP Web服务:http://www.php.net/manual/en/class.soapserver.phpPHP 5 SoapServer的用法?

但是,文档是这个类很差,我对如何创建一个服务器不知道,只是一个客户端。任何人都可以提供一些内容或示例代码?

+1

2点要注意,可以节省您的时间;首先,花点时间了解这个bug:https://bugs.php.net/bug.php?id = 49169;其次,不要依赖模式验证工作,根据我的经验,并不是所有的XML模式规则都被检查过。 – Robin

回答

9

我也一直在努力,尤其是获得与.Net客户端配合使用的代码。我发现了一些适用于PHP客户端的示例,但是当我尝试从.Net客户端调用服务时,这些示例往往失败。我仍然为此而努力,所以我这个问题,要求与返回一个字符串值,一个简单的PHP SoapServer的例子帮助:

String values returned by PHP SoapServer not received by .Net client

不过,虽然我不能获得工作这个基本的例子中,我设法得到了一个返回一个自定义对象数组的例子,所以我将在这里分享这个例子,希望对其他人有所帮助。这个例子定义了一个单一的操作getUsers这需要一个字符串参数消息,只是为了演示消息传递。该操作返回一个数组用户对象。对象也有一个字段消息其中我将收到的值传回服务,仅用于测试目的。我会发布完整的例子; wsdl文档,PHP服务器代码和C#客户端代码。

WSDL文档

<?xml version="1.0" encoding="UTF-8"?> 
<wsdl:definitions 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
    xmlns:tns="http://test-uri/soap/export/" 
    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
    targetNamespace="http://test-uri/soap/export/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 

<wsdl:types> 
<s:schema targetNamespace="http://test-uri/soap/export/" elementFormDefault="qualified"> 
    <s:import namespace="http://microsoft.com/wsdl/types/"/> 

    <s:element name="getUsers"> 
     <s:complexType> 
      <s:sequence> 
       <s:element minOccurs="1" maxOccurs="1" name="message" type="s:string"/> 
      </s:sequence> 
     </s:complexType> 
    </s:element> 

    <s:element name="getUsersResponse"> 
     <s:complexType> 
      <s:sequence> 
       <s:element name="getUsersArray" type="tns:getUsersArray"/> 
      </s:sequence> 
     </s:complexType> 
    </s:element> 

    <s:complexType name="getUsersArray"> 
     <s:sequence> 
      <s:element minOccurs="0" maxOccurs="unbounded" name="User" nillable="true" type="tns:User" /> 
     </s:sequence> 
    </s:complexType> 

    <s:complexType name="User"> 
     <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="id" type="s:string"/> 
      <s:element minOccurs="1" maxOccurs="1" name="firstname" type="s:string"/> 
      <s:element minOccurs="1" maxOccurs="1" name="surname" type="s:string"/> 
      <s:element minOccurs="1" maxOccurs="1" name="message" type="s:string"/> 
     </s:sequence> 
    </s:complexType> 
</s:schema> 
</wsdl:types> 

<wsdl:message name="getUsersSoapIn"> 
<wsdl:part name="parameters" element="tns:getUsers"/> 
</wsdl:message> 
<wsdl:message name="getUsersSoapOut"> 
<wsdl:part name="parameters" element="tns:getUsersResponse"/> 
</wsdl:message> 

<wsdl:portType name="TestSoap"> 
<wsdl:operation name="getUsers"> 
    <wsdl:documentation xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'> 
     Function ("getUsers") 
    </wsdl:documentation> 
    <wsdl:input message="tns:getUsersSoapIn"/> 
    <wsdl:output message="tns:getUsersSoapOut"/> 
</wsdl:operation> 
</wsdl:portType> 

<wsdl:portType name="TestSoap12"> 
<wsdl:operation name="getUsers"> 
    <wsdl:documentation xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'> 
     Function ("getUsers") 
    </wsdl:documentation> 
    <wsdl:input message="tns:getUsersSoapIn"/> 
    <wsdl:output message="tns:getUsersSoapOut"/> 
</wsdl:operation> 
</wsdl:portType> 

<wsdl:binding name="TestSoap" type="tns:TestSoap"> 
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
<wsdl:operation name="getUsers"> 
    <soap:operation soapAction="http://test-uri/soap/export/getUsers" style="document"/> 
    <wsdl:input> 
     <soap:body use="literal"/> 
    </wsdl:input> 
    <wsdl:output> 
     <soap:body use="literal"/> 
    </wsdl:output> 
</wsdl:operation> 
</wsdl:binding> 

<wsdl:binding name="TestSoap12" type="tns:TestSoap12"> 
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
<wsdl:operation name="getUsers"> 
    <soap12:operation soapAction="http://test-uri/soap/export/getUsers" style="document"/> 
    <wsdl:input> 
     <soap12:body use="literal"/> 
    </wsdl:input> 
    <wsdl:output> 
     <soap12:body use="literal"/> 
    </wsdl:output> 
</wsdl:operation> 
</wsdl:binding> 

<wsdl:service name="TestService"> 
<wsdl:port name="TestPort" binding="tns:TestSoap"> 
    <soap:address location="http://url/to/test_server.php"/> 
</wsdl:port> 
<wsdl:port name="TestSoap12" binding="tns:TestSoap12"> 
    <soap12:address location="http://url/to/test_server.php"/> 
</wsdl:port> 
</wsdl:service> 

</wsdl:definitions> 

PHP服务器代码

<?php 
function getUsers($args) { 
    $args = (array)$args; 
    return array("getUsersArray" => array( 
             array("id"=>"1", 
              "firstname"=>"Barney", 
              "surname"=>"Rubble", 
              "message"=>$args["message"]), 
             array("id"=>"2", 
              "firstname"=>"Fred", 
              "surname"=>"Flintstone", 
              "message"=>$args["message"]) 
            ) 
       ); 
} 
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache 
$server = new SoapServer("test.wsdl"); 
$server->addFunction("getUsers"); 
try { 
    $server->handle(); 
} 
catch (Exception $e) { 
    $server->fault('Sender', $e->getMessage()); 
} 
?> 

C#客户端代码

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      WebReference.TestService srv = new WebReference.TestService(); 
      WebReference.User[] users = srv.getUsers("says hello"); 
      foreach (WebReference.User user in users) 
      { 
       MessageBox.Show(user.firstname+" "+user.message); 
      } 
     } 
    } 
} 

就是这样。我希望这个例子对别人有用,并节省他们花费我的时间!

+0

只是为了跟上这一点。我还设法得到了一个使用PHP soap服务的例子,该服务返回一个* single *对象而不是一个数组。取而代之的是从WSDL中删除_getUsersArray_ _c​​omplexType_,并用_User_替换这个复杂类型的引用。然后在服务器代码中,摆脱User数组的一个数组和包装数组。所以像这样:return array(“getUsersArray”=> array(“id”=>“1”,“firstname”=>“Barney”,“surname”=>“Rubble”,“message”=> $ args [信息”]) );显然,_getUsersArray_可以被改变成更合适的名字;只需在WSDL中进行更改即可。 – BruceHill

2

假设你打算提供的PHP服务器功能WSDL上市, 我认为这个链接教程是完美的: php servers

很简单,短,说,你所需要的一切。

... 创建简单的服务器后,只有你可能有问题的事情是“复杂类型”,本教程采用的“新SoapParam”建议解决的主要问题。 PHP返回的关联数组将在某些java/asp客户端生成器中生成预期的OBJECTS。

因此,PHP肥皂服务器将适用于phpclients,c#-asp,java-axis,soapUI ...用PHP SoapServer手动编写wsdl的效果很好。

我不知道为什么,但它真的好像在网上缺乏这方面的信息......忽略了“使用文档 - 文字而不是rpc编码”的帖子 - 这是愚蠢的,未经证实的或者至少在开始时并不重要。

+0

链接已损坏。 – whoan