Javier Tello
Javier Tello

Reputation: 47

PHP SOAPCall null result

I have deployed a SOAP WS with AXIS. I use SOAPClient library and PHP 5.5.9 on Ubuntu 14.04 to call the exposed operations, but when I make the "__SoapCall" it returns nothing. I have also tried with "NuSOAP" library, but I obtain the same result. But when I call "__getLastResponse", It returns the good response (although duplicated), as you can see:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <idXMLReturn xmlns="http://aemetproyecto">PD94bWwgdm...</idXMLReturn>
    </soapenv:Body>
</soapenv:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <idXMLReturn xmlns="http://aemetproyecto">PD94bWwgdm...</idXMLReturn>
    </soapenv:Body>
</soapenv:Envelope>

Here is the WSDL

My PHP code:

<?php

    function generarTabla($id, $formato){
        try{

            // Create the SoapClient instance 
            $url = "http://localhost:8080/axis/services/AemetProyect?wsdl";

            $client = new SoapClient($url, array("trace" => 1, "exception" => 1));

            // Creo XML
            $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
            $xml .= "<!DOCTYPE id [\n";
            $xml .= "<!ELEMENT id (#PCDATA)>\n";
            $xml .= "]>\n";
            $xml .= "<id>".$id."</id>";

            // Codifico XML en Base64
            $Base64xml = base64_encode($xml);

            // Llamada SOAP a DescargarInfoTiempo
            $resultado = $client -> __soapCall("DescargarInfoTiempo",
                                                array($Base64xml));

            //$resultado = $client -> __getLastResponse();
            //echo $resultado;
            //$resultado = $client -> __getLastRequest();
            //echo $resultado;

            echo $resultado;
        } catch (SoapFault $ex){
            $error = "SOAP Fault: (faultcode: {$ex->faultcode}\n"
                                ."faultstring: {$ex->faultstring})";
            echo $error;
        } catch (Exception $e){
            $error = "Exception: {$e->faultstring}";
            echo $error;
        }
    }

?>

I've noticed that the name of return element ("idXMLReturn") is not the same that the name described in WSDL ("DescargarInfoTiempoReturn"). Can this be the problem?

Update

I've tried to do:

$argumens['idXML'] = $Base64xml;
$resultado = $client -> __soapCall("DescargarInfoTiempo",
                                                    array($arguments));

and

$arguments['idXML'] = $Base64xml;
$resultado = $client ->DescargarInfoTiempo($arguments);

But then I get "Notice: Array to string conversion" when I do the call.

Upvotes: 0

Views: 2915

Answers (3)

Javier Tello
Javier Tello

Reputation: 47

As I said above, "I've noticed that the name of return element ("idXMLReturn") is not the same that the name described in WSDL ("DescargarInfoTiempoReturn")" So, that's the problem: AXIS doesn't generate a Envelope that fits to the WSDL schema. It seems java:RPC provider doesn't worry about the return names of operations.

For now, I've solved it by renaming the parameter from "idXML" to "DescargarInfoTiempo", so SOAP response will be "DescargarInfoTiempoReturn" and it will fit with the WSDL schema and PHP will map the response correctly.

Upvotes: 0

The solution is to specify the document literal style as it is explained in Creating a SOAP call using PHP with an XML body

Upvotes: 0

James
James

Reputation: 1769

Your error is in a little detail.

For a call using the SoapClient, you must send the arguments in a array of arguments, instead to send a xml (why you need to do a codification base64? Is some rule of your WebService?). See the PHP docs for get the right way

arguments An array of the arguments to pass to the function. This can be either an ordered or an associative array. Note that most SOAP servers require parameter names to be provided, in which case this must be an associative array.

So, your array arguments* must to be something like this:

$arguments['id'] = $id// if you need base 64, use base64_encode($id) or something
$resultado = $client -> __soapCall("DescargarInfoTiempo",array($arguments));

Other option to do the same thing, is call the function directly:

$arguments['id'] = $id// if you need base 64, use base64_encode($id) or something
    $resultado = $client ->DescargarInfoTiempo($arguments);// note that we don't need array($arguments), just $arguments

See other examples in the comments on the doc page.

Finally, if you still want to create your XML to send, I advise you to do it with other methos like file_get_contents or CURL and don't forget to create your XML with a soap envelop, is needed for the Soap Protocol

*Some old WebServices needs a array with name "parameters"

UPDATE

Look, you're trying to send your $arguments in a array that contains only one element: The XML in your $Base64xml var. I think that The problem still here.

According to PHP manual, you can't send XML in your SoapCall. The var must be a associative array with your vars, so try to do something like this:

$arguments['id'] = $id// this $id var is your function argument(int, string or somenthing else), forget the created XML
    $resultado = $client -> __soapCall("DescargarInfoTiempo",array($arguments));

About the base64 that you need, I never needed it before, but see the marcovtwout comment in this page of PHP manual

If your WSDL file containts a parameter with a base64Binary type, you should not use base64_encode() when passing along your soap vars. When doing the request, the SOAP library automatically base64 encodes your data, so otherwise you'll be encoding it twice.

So, I belive that you don't need to encode your vars.

In short, forget the XML and send only your vars. The PHP SoapClient create the Soap envelop with the corrected encodes and all these things.

If you still with problems doing this, try to enclose your var with some SoapVars. Maybe your WSDL configuration needs this treatment.

I hope this helps

Upvotes: 1

Related Questions