tags:

views:

154

answers:

2

I am writing a SOAP server and have hit a strange problem.

Here's the relevant lines from the server.php

class MyHandler {
    public function __construct() { ... }
    public function __wakeup() { ... }

    public function getPrice() { ... }
}

$server = new SoapServer("my.wsdl", array("soap_version" => SOAP_1_2));

$server->setClass('MyHandler');
$server->addFunction("getPrice");
$server->handle();

Testing this locally (on PHP 5.3) works fine and I'm able to send requests and receive responses.

When I put this onto my development server (PHP 5.2.9), I get this error message:

SoapServer::addFunction(): Tried to add a non existant function 'getPrice'

Apart from the fact that they can't spell, this is very confusing.

I've since managed to work around the issue by changing the addFunction() line to this:

$server->addFunction(SOAP_FUNCTIONS_ALL);

... and it works fine! Of course, examining $server->getFunctions() shows that this adds the __construct() and __wakeup() functions from my class too, which doesn't seem like such a good thing.

What did I do wrong? Is the carpet bomb "add all functions" approach the only way here?

A: 

Hmm, not sure why it's working on PHP 5.3, but from what I understand, SoapServer::setClass() exports all the methods in the given class (ie, your getPrice() method will be exported using that).

SoapServer::addFunction() works specifically with, well functions. Any chance you had a stray getPrice() function lying around in your local environment?

You can test this with commenting out the addFunction() call which should still show your exported methods from "MyHandler".

Using SOAP_FUNCTIONS_ALL is probably a bad idea, as if you remove the setClass() call it actually exports all PHP functions for some reason...

Owen
Nope, I'm quite sure that there's no extra functions being included: there's only one include in the script (including the MyHandler class), and even the contents of that include are pasted into the script, there's no difference.
nickf
Did you try removing the addFunction() call? The setClass() should be sufficient to export all the methods in your class anyhow.
Owen
+1  A: 

Using addFunction() tells it to look for a function named getPrice() on its own, outside of a class. This doesn't exist, so is causing the error.

Using addClass() will automatically add all the functions from MyHandler, so you shouldn't need to call addFunction(), getPrice() should have already been added.

Additionally, there's an open ticket (for PHP 5.2.9) on bugs.php.net which seems to indicate that there's no way of adding a class method using addFunction(): http://bugs.php.net/bug.php?id=47919

I don't have access to PHP 5.3 though, so not sure how things may have changed I'm afraid...

Dave Challis