Returning a PHP array with SOAP

software development

#1

I’ve asked this question on multiple sites (bytes, stackoverflow, even sent a message to Dreamhost support) and it hasn’t been answered anywhere. I’m completely stuck at this point and I really want to move along.

I’m writing a SOAP service to provide an API for my site. Right now what I’m trying to do is return a paginated list of news posts. Each post has 8 elements, all with different types, listed below:

Title (string)
LinkId (int)
Date (int)
Author (string)
Content (string)
Id (int)
Icon (int)
Edited (boolean)

Each page will return 25 results in a nested array called News. There will also be a boolean value called HasMorePages, doing just what it says. The final array should look like this:

[code]Array
(
[HasMorePages] => 1
[News] => Array
(
[0] => Array
(
[Title] => “some title”
[LinkId] => 100
[Date] => (timestamp)
[Author] => “HaLo2FrEeEk”
[Content] => “Some text”
[Id] => 170
[Icon] => 1
[Edited] => 0
)

[1] => Array
    (
    [...]
    )[/code]

And I should be able to get at this in a C# application by running client.GetNews(int page), which should return a NewsResult object, which has two properties: HasMorePages and News. News is an array of NewsItems, each of which has the 8 properties I listed above.

I’ve written the function that returns this array and tested it, it works, but I just get an empty result. I had this working when I was simply returning a string with the 25 news posts’ titles, separated by a newline, but I can’t figure out how to serialize the array in PHP to return it through SOAP. I don’t even know if it’s a PHP problem or a problem with my WSDL file, here is my WSDL file though:

http://api.infectionist.com/soap.wsdl

There are a few XSD’s imported, too. If anyone wants it, I’ll post up my function where I’m getting the news information, too.

Please, if anyone can help me out I’ll be super grateful. I’ve been at this for days now and it’s driving me crazy, especially because my posts on other sites are being ignored.


#2

SOAP is distilled pain and suffering. There is a very good reason why the DreamHost API is not based on SOAP.


#3

Regardless, I still need to do it. I’ll be offering both SOAP and JSON endpoints. SOAP will be used for C# applications on a PC and JSON will be used in an Android app. I know it’s a pain, but can you help me figure it out?


#4

Never worked with it personally, but it may help to post the PHP code you’re using for the endpoint.


#5

Sorry, I didn’t get an email for your reply so I thought no one responded. Here is my server code sans the database connection:

http://api.infectionist.com/servercode.php

And the client code, which is simple:

[php]class GetNews {
var $page;

function GetNews($page) {
$this->page = $page;
}
}

echo “

”;
$client = new SoapClient(“soap.wsdl”, array(‘trace’ => 1, ‘classmap’ => array(“GetNews” => “GetNews”)));
$p = new GetNews(0);
print_r($client->GetNews($p));
echo “
”;[/php]

The issue has changed slightly though. At this point I can get a return using my PHP client, but when I add a reference into a Visual Studio project and try to call my methods, I get a null return. The method call doesn’t fail, but when I try to access any of the properties of the return object (a NewsResponse object), I get an error, because the response is null. I monitored my betwork traffic to see if the proper messages were being sent and recieved and they were, I got the message envelope and the response envelope, they’re identical to what the PHP client gets, but C# isn’t recognizing it. I don’t know what to do at this point.


#6

Did you ever get this to work?

I’m starting out with Soap, and found this thread when looking for SOAP Arrays to C#.


#7

Yeah I did. SOAP is very picky, your return object (and its children) in the WSDL has to have a matching PHP class. For example (pseudo code):

<complexType name="Test"> <sequence> <element minOccurs="0" name="Value" type="int" /> </sequence> </complexType> <element name="Test" nillable="true" type="tns:Test" />

That’s an example object definition, to return this object from your SOAP service, you must have a function that returns a PHP class with the same name and elements, like this:

[php]class Test {
var $Value;

function Test() {
$this->Value = “Hello World!”;
}
}

function GetTest() {
$ret = new Test();
return $ret;
}[/code]

Keep in mind I haven’t included everything you need to make a SOAP service work, there’s more to it. This is just one of the things I was hung up on, took me a while to figure out, especially because I had a working WSDL from another service to look at, but I didn’t have access to the code that drove it, so I had to figure it out myself.


#8

Is their some setting in the PHP.INI File I can change ?

I run my PHP & WSDL on a local server & it works with my C# App.
I run the Same PHP & WSDL File on DreamHost and it fails :frowning:

The only change in the WSDL File is I either point to www.gw4y.com or 192.168.1.17.

included is the SOAP Env Envelopes I Get from Both Servers.

on www.gw4y.com I get this

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:HelloService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.gw4y.com" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <ns1:GetCardTypeResponse>
         <CardReturn xsi:type="ns2:ACard">
            <sCardID xsi:type="xsd:string">PHP4139</sCardID>
            <sCardName xsi:type="xsd:string">A 4139 Card</sCardName>
            <sCardDescription xsi:type="xsd:string">Quad Die Card</sCardDescription>
         </CardReturn>
      </ns1:GetCardTypeResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

On 192.168.1.17 I Get This

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://192.168.1.17">
   <SOAP-ENV:Body>
      <ns1:GetCardTypeResponse>
         <CardReturn>
            <sCardID>PHP4139</sCardID>
            <sCardName>A 4139 Card</sCardName>
            <sCardDescription>Quad Die Card</sCardDescription>
         </CardReturn>
      </ns1:GetCardTypeResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>