PHP 5 SoapServer 的使用?

发布于 2024-12-09 11:02:05 字数 225 浏览 0 评论 0原文

我正在尝试使用本机 SoapServer 类在 PHP 中创建一个简单的 SOAP Web 服务: http://www. php.net/manual/en/class.soapserver.php

但是,此类的文档非常差,我不知道如何创建服务器,只是一个客户端。谁能提供一些图或示例代码?

I'm trying to create a simple SOAP webservice in PHP using the native SoapServer class: http://www.php.net/manual/en/class.soapserver.php

However, the documentation is very poor on this class and i have no idea on how to create a Server, just a client. Can anyone provide some tuts or sample code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱殇璃 2024-12-16 11:02:05

我也一直在努力解决这个问题,尤其是获取与 .Net 客户端配合良好的代码。我发现了与 PHP 客户端配合良好的示例,但当我尝试从 .Net 客户端调用服务时,这些示例通常会失败。我仍然在努力解决这个问题,因此我的这个问题请求帮助一个简单的 PHP SoapServer 示例,该示例返回一个字符串值:

PHP SoapServer 返回的字符串值未被 .Net 客户端接收

但是,虽然我无法让这个基本示例正常工作,但我已经设法获取一个返回自定义对象数组的示例,因此我将在这里分享这个示例,希望对其他人有所帮助。此示例定义了一个操作getUsers,它采用字符串参数message,只是为了演示消息传递。此操作返回一个User对象数组。 User 对象还有一个 message 字段,我将接收到的值传回服务中,仅用于测试目的。我将发布完整的示例; 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);
            }
        }
    }
}

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

I have also been struggling with this, especially getting code that works well with .Net clients. I have found examples that work well with PHP clients, but often these examples fail when I try to call the service from a .Net client. I am still struggling with this, hence this question of mine asking for help with a simple PHP SoapServer example that returns a string value:

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

But, although I can't get this basic example working, I have managed to get an example working that returns an array of custom object, so I will share this example here in the hope that it will be helpful to others. This example defines a single operation getUsers which takes a string parameter message, just to demonstrate message passing. This operation returns an array of User objects. The User object also has a field message where I pass back the value received into the service, just for testing purposes. I will post the complete example; wsdl document, PHP server code and C# client code.

WSDL Document

<?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 Server Code

<?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# Client Code

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);
            }
        }
    }
}

That's it. I hope this example is useful to others and saves them the hours that this has cost me!!

掩耳倾听 2024-12-16 11:02:05

假设您打算提供 PHP 服务器函数的 WSDL 列表,
我认为这个链接上的教程是完美的:
php 服务器

它很简单,简短,说明了一切你需要。

...
创建简单的服务器后,您可能遇到的唯一问题是“复杂类型”,本教程通过推荐使用“new SoapParam”解决了主要问题。 PHP 返回的关联数组将在某些 java/asp 客户端生成器中生成预期的对象。

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

我不知道为什么,但网上似乎确实缺乏这方面的信息...忽略那些说“使用文档文字而不是 rpc 编码”的帖子 - 这是愚蠢的,未经证实的或至少不重要作为开始。

Assuming that you intend to provide WSDL listing of PHP-server functions,
I think that tutorial on this link is perfect:
php servers

it is simple, short and says everything that you need.

...
after creating simple servers, only thing that you probably will have problems with are "complex types", and this tutorial solves main problem by recommending using "new SoapParam". Associative arrays returned by PHP will produce intended OBJECTS in some java/asp client-generators.

So, PHP Soap server will be ok for phpclients, c#-asp, java-axis, soapUI... Manually written wsdl with php SoapServer works great.

I do not know why, but it really seems like there is a lack of information about this on the net... ignoring the posts saying "use document-literal instead of rpc-encoded" - it is stupid, unproven or at least unimportant for beginning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文