SOAP request in PHP with CURL

I am sending a SOAP request and the response is 200 ok but I am struggling to output the $response.

This is the website for the request Calculator Web Service and also the xml file document tree http://dneonline.com/calculator.asmx?wsdl

Here is my php code;

<?php
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Add xmlns="http://tempuri.org/">
      <intA>1</intA>
      <intB>2</intB>
    </Add>
  </soap:Body>
</soap:Envelope>';

$url = "http://dneonline.com/calculator.asmx?wsdl";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

$headers = array();
array_push($headers, "Content-Type: text/xml; charset=utf-8");
array_push($headers, "Accept: text/xml");
array_push($headers, "Cache-Control: no-cache");
array_push($headers, "Pragma: no-cache");
array_push($headers, "SOAPAction: http://tempuri.org/Add");

if($xml != null) {
    curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml");
    array_push($headers, "Content-Length: " . strlen($xml));
}

// curl_setopt($ch, CURLOPT_USERPWD, "user_name:password"); /* If required */
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "<pre>";
print_r($response->AddResponse);
echo "</pre>";
?>

$response will be a string, probably full of XML; it won’t have any properties. Just use echo $response to see its value. PHP does have a SOAP client built in, you might be better off looking into using that instead of cURL.

Well, not really a question in there… I will guess you mean you want to know how to parse and review the output from this cURL process. Well, it’s a SOAP item, so, take out the soap titles, convert it to XML and the then an array… Something like that. Here is the first part:

//  Remove the body tags...    ( Optional.. )
$soap = str_replace("<soap:Body>","",$response);
$soap_data = str_replace("</soap:Body>","",$soap);
//  Converting Soap to XML
$xml = simplexml_load_string($soap_data);
//  Display the data
if ($xml === false) {
    echo "Failed loading XML: ";
    foreach(libxml_get_errors() as $error) {
        echo "<br>", $error->message;
    }
} else {
    print_r($xml);
}

Something loosely like that should work for you… Once in XML format, you parse thru it as needed, you can convert this to a standard php array too, if needed…

The current code returns bool(false) for $response currently. No other information. If you copy/paste the code then you will get the same output.

When I echo $xml it returns 1 2.

Thank you ErnieAlex. When adding this code I return Failed loading XML: (but no other error message).

Well, I am not sure with all those array pushes, cURL and other codes…
This is a sample of how you retrieve data using SOAP under PHP.

try {
 $client = new SoapClient('http://www.webservicex.net/stockquote.asmx?WSDL');
 $val = array('symbol' =-->'ORCL');
 $results = $client->GetQuote($val);
 
 /* GetQuoteResult is from the GetQuoteResponse element in the WSDL */
 $output = $results->GetQuoteResult;
 echo $output;
} catch (SoapFault $e) {
 echo $e->getMessage();
}

It is not for your URL, but, as you see, it is much simpler than your version. Tomorrow, I will look at that site and see why it is not working. But, perhaps you might want to do it a more conventual way…

thank you for the support here ErnieAlex.

I have been trying to use SoapClient but continuously get the error:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘https…’

I have looked in the php.ini file to address any exceptions and don’t appear to get any success if I make adjustments there. This is the first time I have used SOAP and while it appears straight forward to me, I have some stumbling blocks to try to work though. As I have some experience of using cURL I have taken this route due to the resistance I am experiencing with SoapClient.

I reworked the code a little to remove those array pushes:

<?php
$xml = '<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

  <soap:Body>

    <Add xmlns="http://tempuri.org/">

      <intA>1</intA>

      <intB>2</intB>

    </Add>

  </soap:Body>

</soap:Envelope>';

$url = "http://dneonline.com/calculator.asmx?wsdl";

$ch = curl_init();

curl_setopt_array($ch, [

  CURLOPT_URL => $url,

  CURLOPT_RETURNTRANSFER => true,

  CURLOPT_SSL_VERIFYPEER, false,

  CURLOPT_SSL_VERIFYHOST, 0,

  CURLOPT_CUSTOMREQUEST => "POST",

  CURLOPT_POSTFIELDS => $xml,

  CURLOPT_HTTPHEADER => ["content-type: text/xml",

                          "cache-control: no-cache",

                          "Content-Length: " . strlen($xml)],

]);

// // curl_setopt($ch, CURLOPT_USERPWD, "user_name:password"); /* If required */

$response = curl_exec($ch);

curl_close($ch);

$soap = str_replace("<soap:Body>","",$response);

$soap_data = str_replace("</soap:Body>","",$soap);

//  Converting Soap to XML

$xmlcon = simplexml_load_string($soap_data);

//  Display the data

if ($xmlcon === false) {

    echo "Failed loading XML: ";

    foreach(libxml_get_errors() as $error) {

        echo "<br>", $error->message;

    }

} else {

    print_r($xmlcon);

}
?>

Hopefully you can get some more insight into this tomorrow!

Well, it is tomorrow now. Ha! I have time later today to try to get this to work on my local server.
I have never needed to use SOAP, but, know the basics. I will try to use this last code you posted.
You can use the PHP info command to review your PHP settings instead of using the INI file.
To do that, create a new page with just this one line of code in it. Run it on your server. It will show you, well, everything in your configuration. Makes it handy…

<?PHP phpinfo(); ?>

You will see ALL of your PHP, cURL and SOAP settings in that list. For SOAP, you just need to make sure it is enabled. If not you can do so using a ini_set() function… More on SOAP later when free…

Great thanks! I was able to make the required edits to the php.ini file in my local xampp server then after restart the SoapClient now works… On our development server it still kicks the same error. From the phpinfo() command I have soap enabled but with this being a wsdl parsing error I am not sure how to fix that.

Well, you can use ini_set() functions to get around things on the development server.
First, on that server, use the phpinfo() file you created and run it remotely. Then, look at the
cURL and SOAP settings and see if they are the same for both the local Xamp and development server.
I bet they are not the same. Short on time right now. Will look at it more later in my day…

Well, let’s just go back to the basics… Try this code as-is…

<?php

// Initialize WS with the WSDL
$client = new SoapClient("http://dneonline.com/calculator.asmx?wsdl");

// Set request params
$params = array(
  "intA" => 1,        //  This is the variable that the WSDL requested as one of it's inputs
  "intB" => 2         //  This is another variable that the WSDL needs as an input
);

// Invoke WS method (Function1) with the request params 
$response = $client->__soapCall("Add", array($params));

// Print WS response
var_dump($response);
?>

This should give you this results:

object(stdClass)[2]
  public 'AddResult' => int 3

And, therefore, if you want the public results, you use $response->AddResult… Like this:

<?php

// Initialize WS with the WSDL
$client = new SoapClient("http://dneonline.com/calculator.asmx?wsdl");

// Set request params
$params = array(
  "intA" => 1,        //  This is the variable that the WSDL requested as one of it's inputs
  "intB" => 2         //  This is another variable that the WSDL needs as an input
);

// Invoke WS method (Function1) with the request params 
$response = $client->__soapCall("Add", array($params));

// Print WS response
echo "The results = " . $response->AddResult;
?>

The results is created as an OBJECT. Therefore, you select whatever the public name for the data inside the object.

NOTE: This version does not require cURL, just simple builtin calls using standard PHP. I think this is what you really need. Also, you could use variables for the inputs instead of hard-coding them. I did it this way just to make it the simplest example. Hope it works for you.

Great thank you ErnieAlex, this is indeed working as described!

Great! You are welcome! See you in your next post…

Sponsor our Newsletter | Privacy Policy | Terms of Service