Использование PHP 5 SoapServer? - PullRequest
11 голосов
/ 13 октября 2011

Я пытаюсь создать простой веб-сервис SOAP на PHP, используя собственный класс SoapServer: http://www.php.net/manual/en/class.soapserver.php

Однако документация по этому классу очень плохая, и я понятия не имею, как создать сервер, просто клиент. Кто-нибудь может предоставить некоторые ТУТС или образец кода?

Ответы [ 2 ]

9 голосов
/ 20 ноября 2011

Я также боролся с этим, особенно с получением кода, который хорошо работает с клиентами .Net. Я нашел примеры, которые хорошо работают с PHP-клиентами, но часто эти примеры терпят неудачу, когда я пытаюсь вызвать службу из .Net-клиента. Я все еще борюсь с этим, поэтому этот мой вопрос просит помощи в простом примере PHP SoapServer, который возвращает строковое значение:

Строковые значения, возвращенные PHP SoapServer, не полученные клиентом .Net

Но, хотя я не могу заставить этот базовый пример работать, мне удалось получить работающий пример, который возвращает массив пользовательских объектов, поэтому я поделюсь этим примером здесь в надежде, что он будет полезен для других. В этом примере определяется одна операция getUsers , которая принимает строку параметр сообщение только для демонстрации передачи сообщения. Эта операция возвращает массив объектов 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);
            }
        }
    }
}

Вот и все. Я надеюсь, что этот пример полезен для других и сэкономит им часы, которые мне это стоило !!

2 голосов
/ 28 октября 2011

Предполагая, что вы намереваетесь предоставить WSDL-список функций PHP-сервера, Я думаю, что учебник по этой ссылке идеально подходит: php серверы

это просто, коротко и говорит все, что вам нужно.

... после создания простых серверов единственное, с чем у вас, вероятно, будут проблемы, это " сложных типов ", и это руководство решает основную проблему, рекомендуя использовать "new SoapParam". Ассоциативные массивы, возвращаемые PHP, будут создавать намеченные ОБЪЕКТЫ в некоторых клиентских генераторах java / asp.

Итак, сервер PHP Soap подойдет для phpclients, c # -asp, java-axis, soapUI ... Написанный вручную wsdl с php SoapServer отлично работает.

Я не знаю, почему, но на самом деле кажется, что в сети не хватает информации об этом ... игнорирование сообщений о том, что "используйте document-literal вместо rpc-encoded" - это глупо, недоказано или по крайней мере, неважно для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...