PHP Which Soap Lib to Use

SOAP libraries for PHP

I know of these:

  • Nusoap
  • PHP SOAP Extension (based on libxml)
  • WSO2 Web Services Framework for PHP
  • Zend_Soap

PHP SOAP client Tutorial/Recommendation?

Have you tried SoapClient which is already built into PHP?

There is one tutorial: PHP - Soap Client calling .NET Web service

Here is another one, even though it was created for zend developers it should work fine.

How to build a correct SOAP request with PHP

"Is there a more direct approach where I could write the XML?"

By using a SoapVar and setting the encode parameter of the constructor to XSD_ANYXML you can write the raw XML.

There should be a way where the WSDL helps build the XML though.

You could try something like this:

$wsdl   = "http://api.notificationmessaging.com/NMSOAP/NotificationService?wsdl"; 
$client = new SoapClient($wsdl, array( 'soap_version' => SOAP_1_1,
'trace' => true,
));
try {

$xml = '<arg0>
<content>
<entry>
<key>1</key>
<value>
<![CDATA[
<table width="600">
<tr>
<td>
<font size="2" face="Arial">Our powerful algorithms already
found a matching profile that matches your criteria:
<br>Celina72 </font>
<img src="http://mypath/to/my/image.gif" width="50"
height="50" border="0" />
</td>]]></value>
</entry>
</content>
<dyn>
<entry>
<key>FIRSTNAME</key>
<value>john</value>
</entry>
</dyn>
<email>johnblum@flowerpower.com</email>
<encrypt>BdX7CqkmjSivyBgIcZoN4sPVLkx7FaXGiwsO</encrypt>
<notificationId>6464</notificationId>
<random>985A8B992601985A</random>
<senddate>2008-12-12T00:00:00</senddate>
<synchrotype>NOTHING</synchrotype>
<uidkey>EMAIL</uidkey>
</arg0>';

$args = array(new SoapVar($xml, XSD_ANYXML));
$res = $client->__soapCall('sendObject', $args);
return $res;
} catch (SoapFault $e) {
echo "Error: {$e}";
}

echo "<hr>Last Request";
echo "<pre>", htmlspecialchars($client->__getLastRequest()), "</pre>";

PHP Soap client with complex types

For those who'll get the same problem.
My solution is to use nusoap (https://github.com/yaim/nusoap-php7). This library allows you to make complicated requests, including SWA (SOAP with Attachments).
Here is working code for my question:

$person = array("personId"=>$id, "consentConfirmed"=>$confirmed);
$data = array(
"reportParams"=>new soapval("reportParams", "personCreditReportParams", $person, false, $namespace)
);
$result = $client->call("getCreditReportTypes", $data, $namespace);

P.S. I've tried some generators and no one could make correct request, although classes were generated correctly.

Soap Client Complex Type PHP Request

I found the solution!. It seems the PHP -> .NET web service comparability issue. So from PHP the complex type SOAP (this kind of format) can't access I found some usefull post here. So I switched SOAP to plain XML request with CURL and it seems working fine!. Also from WSDL link we can extract the request template using this online service .
So my final code look like below.

$xml_data = "<?xml version='1.0' encoding='UTF-8'?>
<s12:Envelope xmlns:s12='http://www.w3.org/2003/05/soap-envelope'>
<s12:Header>
<ns1:SecurityHeaderElement xmlns:ns1='http://www.navicure.com/2009/11/NavicureSubmissionService'>
<ns1:originatingIdentifier>****</ns1:originatingIdentifier>
<ns1:submitterIdentifier>****</ns1:submitterIdentifier>
<ns1:submitterPassword>***</ns1:submitterPassword>
<ns1:submissionId>?999?</ns1:submissionId>
</ns1:SecurityHeaderElement>
</s12:Header>
<s12:Body>
<ns1:SubmitAnsiSingleRequestElement xmlns:ns1='http://www.navicure.com/2009/11/NavicureSubmissionService'>
<ns1:timeout>60</ns1:timeout>
<ns1:transactionType>E</ns1:transactionType>
<ns1:submittedAnsiVersion>5010</ns1:submittedAnsiVersion>
<ns1:resultAnsiVersion>5010</ns1:resultAnsiVersion>
<ns1:submitterSubmissionId></ns1:submitterSubmissionId>
<ns1:processingOption>R</ns1:processingOption>
<ns1:payload>EDI270Payload</ns1:payload>
</ns1:SubmitAnsiSingleRequestElement>
</s12:Body>
</s12:Envelope>";
$URL = "https://ww3.navicure.com:7000/webservices/NavicureSubmissionService";

$ch = curl_init($URL);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml_data");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);

print_r($output);

Hope this will help someone else in future.

How to make a PHP SOAP client and store the result xml in php variables

PHP has a native SoapClient class that makes it easy to call SOAP services. It provides a simple interface allowing you to use native PHP arrays and objects for the request and response data, and handles the intricacies of the SOAP envelope and WSDL.

// create a new SoapClient and pass it the WSDL
$client = new SoapClient('http://webservices.cibg.nl/Ribiz/OpenbaarV2.asmx?WSDL');

// define the input parameters for the webservice call
$params = array('WebSite' => 'Ribiz', 'RegistrationNumber' => 'xxxxxxxxxx');
// invoke the ListHcpApprox3 method
$response = $client->ListHcpApprox3($params);

// print out the response to see its structure
var_dump($response);

You can pick the variables out of the response like this:

$data = $response->ListHcpApprox->ListHcpApprox3
$HcpNumber = $data->HcpNumber;
$BirthSurname = $data->BirthSurname;

echo $HcpNumber;

Parsing a live SOAP data stream with PHP

Ok, the goal is to "stream a SOAP reponse" with a "timeout" and/or in an "interval"?

I suggest to override the SoapClient __doRequest() method and implement a custom connection via fsockopen() and stream the data with stream_get_contents().
Now you get a stream of XML data and what you want is in the middle of it.
You would have to extract the XML envelope or parts of it, probably using string functions or by using preg_match to fetch the inner content.

The following code provides a SoapClientTimeout class, where the timeout is set via stream_set_timeout(). This is for use-case, when the server has slow responses and you want to make sure, when to end listening.

I suggest to play around with it and tweak the timeout behavior on the socket.
Because, what you want is to stop listening after a while (interval fetch).
So, you cloud try to combine timeout with blocking, to stop reading from the stream after a while:

$timeout = 60; // seconds
stream_set_blocking($socket, true);
stream_set_timeout($socket, $timeout);

When you have a stream, which blocks after 1 minute and closes,
you need a loop (with a solid exit condition) triggering the next request.


class SoapClientTimeout extends SoapClient
{
public function __construct ($wsdl, $options = null)
{
if (!$options) $options = [];

$this->_connectionTimeout = @$options['connection_timeout'] ?: ini_get ('default_socket_timeout');
$this->_socketTimeout = @$options['socket_timeout'] ?: ini_get ('default_socket_timeout');
unset ($options['socket_timeout']);

parent::__construct($wsdl, $options);
}

/**
* Override parent __doRequest and add "timeout" functionality.
*/
public function __doRequest ($request, $location, $action, $version, $one_way = 0)
{
// fetch host, port, and scheme from url.
$url_parts = parse_url($location);

$host = $url_parts['host'];
$port = @$url_parts['port'] ?: ($url_parts['scheme'] == 'https' ? 443 : 80);
$length = strlen ($request);

// create HTTP SOAP request.
$http_req = "POST $location HTTP/1.0\r\n";
$http_req .= "Host: $host\r\n";
$http_req .= "SoapAction: $action\r\n";
$http_req .= "Content-Type: text/xml; charset=utf-8\r\n";
$http_req .= "Content-Length: $length\r\n";
$http_req .= "\r\n";
$http_req .= $request;

// switch to SSL, when requested
if ($url_parts['scheme'] == 'https') $host = 'ssl://'.$host;

// connect
$socket = @fsockopen($host, $port, $errno, $errstr, $this->_connectionTimeout);

if (!$socket) {
throw new SoapFault('Client',"Failed to connect to SOAP server ($location): $errstr");
}

// send request with socket timeout
stream_set_timeout($socket, $this->_socketTimeout);
fwrite ($socket, $http_req);

// start reading the response.
$http_response = stream_get_contents($socket);

// close the socket and throw an exception if we timed out.
$info = stream_get_meta_data($socket);
fclose ($socket);
if ($info['timed_out']) {
throw new SoapFault ('Client', "HTTP timeout contacting $location");
}

// the stream contains XML data
// lets extract the XML from the HTTP response and return it.
$response = preg_replace (
'/
\A # Start of string
.*? # Match any number of characters (as few as possible)
^ # Start of line
\r # Carriage Return
$ # End of line
/smx',
'', $http_response
);
return $response;
}

}

PHP SOAP client over IPv4

A SOAP request is a socket connection, so you can use socket_context options.
Use stream_context_create() to bind your request to a specified IP.

stream_context_create(['socket' => ['bindto' => '123.123.123.123:0']]);

Set 0 for port number so PHP will set this automatically.



Related Topics



Leave a reply



Submit