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?
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!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With