3

I'm experiencing a problem with my SOAP solution. Sometimes I get an error saying the following:

Function (functionA) is not a valid method for this service

Edit 8 months later Although I could not find the cause of the problem I was able to work around it. Whenever I recieve an response from the API I check for the SoapFault and just send another identical request and use the answer that comes back the second time.(posted as an answer)

This occurs in calls from PHP like:

functionA() - expected response
functionA() - expected response
functionA() - SoapFault
functionA() - expected response

Same result is to be expected in all the above calls and the same parameters are used(if any). Since it's working fine for almost all calls I know that the function and the corresponding WSDL is there.

What I thougt were the problem was caching an old version which would not have that function. I tried disabling the caching with:

ini_set("soap.wsdl_cache_enabled", "0");

And makeing every call with added with a random dummy parameter as well as disabling it when I use Zend_SoapClient.

'cache_wsdl' = false

I hope someone could point me in any direction or have any direct suggestion on what could be the cause.

My code looks like:

public function __construct()
{
        $wsdl =  "http://catlovers.nl/index.php?wsdl&dummy=".rand(1000,9999);

        $this->_client = new Zend_Soap_Client($wsdl, array(
            'soapVersion' => SOAP_1_1,
            'cache_wsdl' => false 

        ));
        $this->_client->setWsdlCache(false);
}

function __call($name, $arguments) // Calls are made this way
{
    array_unshift($arguments, $this->_apiKey, $this->_user, $this->_password);
    return call_user_func_array(array($this->_client, $name), $arguments);
}
public function getCat()
{
    return ($this->__call('getCat',array()));
}

On "the other side" I have:

$server = new nusoap_server();

$server->wsdl->addComplexType('Cat', ....

$server->register( 'getCat', return Cat ...

function getCat($apikey, $email, $password)
{
  $cat = $db->get("redCat");
  return $cat;
}
Alex
  • 423
  • 8
  • 23
  • Aren't SOAP service functions supposed tobe declared and used with the appropriate params? i.e. `functionA(int x, int y)` Does adding dummy params result in a SoapFault? – undefined Feb 08 '13 at 09:32
  • Yes they are and that's the way I'm using them as well! I'm calling them with parameters according to what I have declared. The thing is that it works like 90% of the time and the rest of the time it's like the method is not even there. – Alex Feb 08 '13 at 09:34
  • Are You accesing the service through https? – undefined Feb 08 '13 at 09:37
  • @xyu Nope I'm not. If it matters; both the PHP and the SOAP service are on the same domain. – Alex Feb 08 '13 at 09:39
  • See what is the message of the SoapFault. If that doesn't help try calling the function directlyin PHP to see if it yields warnings, notices or other simmilar stuff. Echoing something other than the function output screws up the wsdl. – undefined Feb 08 '13 at 09:42
  • I know. The message is "Function (functionA) is not a valid method for this service". Which is pretty obvious and when I just refresh(no change in code) the page works as I want it to. As I stated earlier I know that the function is indeed there and that it's declared properly. – Alex Feb 08 '13 at 09:45
  • [related](http://stackoverflow.com/questions/10817430/php-soapclient-request-not-a-valid-method-for-this-service) – undefined Feb 08 '13 at 09:52
  • You haven't provided enough of a code sample for anybody to help you and your question does not give any hint as to what your code my look like. – Charles D Pantoga Feb 25 '13 at 20:44
  • Now I have added code to the question. The only shared code between all functions is the one that I've posted. – Alex Feb 26 '13 at 09:01
  • Is the `soapVersion` the same on the client and the server? – undefined Feb 28 '13 at 12:02
  • The client is sending SOAP_1_1, I can't find any reference in the server code to determine what it uses. I believe that the server being Nusoap can handle both SOAP_1_1 and SOAP_1_2 requests. – Alex Feb 28 '13 at 12:18
  • @Alex It would be great if you paste the whole server-side code to some pastebin and post a link to it – Timur Feb 28 '13 at 15:53
  • @Timur I can try to copy out some of the code to show you what it looks like. – Alex Mar 01 '13 at 15:05
  • @Alex Yes, do this, please – Timur Mar 01 '13 at 19:09

3 Answers3

3

First of all, try to call function using built-in SoapClient class and printing debug information:

$wsdl =  "http://abcd.com/index.php?wsdl&dummy=".rand(1000,9999);
$soap = new SoapClient($wsdl, array(
   'cache_wsdl' => WSDL_CACHE_NONE,
   'trace' => true,
));

try {
    var_dump($soap->functionA());
} catch ( Exception $ex ) {
    var_dump($ex);
}
var_dump($soap->__getLastRequest());
var_dump($soap->__getLastRequestHeaders());
var_dump($soap->__getLastResponse());
var_dump($soap->__getLastResponseHeaders());

This way you'll know where is the problem. If everything is ok all the time, the problem is in Zend's class. If not, look what service responds. May be there is some server-side error or dummy generation with such id fails

Timur
  • 6,668
  • 1
  • 28
  • 37
  • I've checked that and the problem is the response being "Function (functionA) is not a valid method for this service". – Alex Feb 26 '13 at 09:58
  • @Alex then try to request your `wsdl` multiple times with different `dummy` parameter and check if there is your function. If some times there is no such function, check code that depends on `dummy` request parameter - may be some times there is no such function. If so, correct code that generates functions for service – Timur Feb 26 '13 at 20:59
  • there is no code depending on the dummy parameter. The parameter is just there to make sure the requests are different and therefore does not trigger any cached requests. – Alex Feb 28 '13 at 09:19
1

I guess your problem is related to nusoap, because for many years I'm using PHP soap server/client and I never faced this problem. (but I always had strange problems with nusoap lib)

currently I'm using jool.nl web service helper which is very powerfull yet neat and object oriented library not only makes coding easier and cleaner but also provides you object oriented approach to web service designing. It also provides a nice web interface for your web service with documentation.

As this library uses internal PHP SOAP server I'm pretty sure you're problem will be disappear then.

I suggest you to give it a try and I'm sure if you make your first web service with this library you will never try something else.

I hope this helps you.

Boynux
  • 5,958
  • 2
  • 21
  • 29
  • It'll sure take some time to change from nusoap to some other library. But I might try out your solution when I got some time on my hands. – Alex Feb 28 '13 at 09:22
  • I worked a lot with NuSOAP. It has some bugs, but latest versions work good. And I am not faced such problem – Timur Feb 28 '13 at 15:50
0

So the problem was still there after trying other solutions so I was never able to find underlying cause of the problem. On the other hand I found a way to work around the problem that has been working since I wrote it. This is how my call to the API looks like with user,password and key for authentication.

function __call($name, $arguments)
{
    /* Using the stored data to ensure that the user is allowed to access */
    /* ............... */

    array_unshift($arguments, $this->_apiKey, $this->_user, $this->_password);
    $call = call_user_func_array(array($this->_client, $name), $arguments);
    if(isset($call->faultstring) && substr(trim($call->faultstring),0,7) == "Function")
    {
        $recall = call_user_func_array(array($this->_client, $name), $arguments);
        return $recall;
    }
    else
        return $call;
}

This is basicly: if it doesn't work the first time just try again.

Alex
  • 423
  • 8
  • 23