Link to home
Start Free TrialLog in
Avatar of fionafenton
fionafentonFlag for United Kingdom of Great Britain and Northern Ireland

asked on

PHP and SOAP Woes

Probably easier if I start with some background info. I have a property portal website and normally an agent would provide me with a link to an xml file containing details of their properties. I set up a cron job and collect their xml file from the url and update our database. Easy.

However, several of our agents are switching to an Estate Agent software package called Hecktor via http://www.la-boite-immo.com/. When requesting a link to an xml file they then referred me to krier.fr who provided me with login details to their SOAP web service and directed me to this page http://alize.krier.fr/AlizeWS/ExportXmlWs.asmx. After several exchanges of emails I was finally able to see the xml data in a browser window by going to this page and entering the login details http://www.soapclient.com/soapclient?template=/clientform.html&fn=soapform&SoapTemplate=/SoapResult.html&SoapWSDL=http://alize.krier.fr/AlizeWS/ExportXmlWS.asmx%3Fwsdl&_ArraySize=2
(Obviously I can't give any log in details)
This is a snippet of what I'm seeing
soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetXmlDataResponse xmlns="http://tempuri.org/">
<GetXmlDataResult>
<lots>
<lot>
......
</lot>
<lot>
.......
</lot>
etc...
</lots>
</GetXmlDataResult>
</GetXmlDataResponse>
</soap:Body>
</soap:Envelope>

Open in new window


What I want to do is capture the data and save it (Basically everything between <lots></lots>). I can then parse it and update our database.
After hours of trawling the internet I have got this far
$client = new SoapClient("http://alize.krier.fr/AlizeWS/ExportXmlWs.asmx?wsdl", array('loginAnnonceur' => "xxxxxx",
                                            'motDePasseAnnonceur'    => "xxxxxx",
                                            'codeAgence' => "xxxxxx",
					    'trace' => 1));
$params=array();
$result = $client->GetXmlData($params);

Open in new window

I know I need to put something in $params but have no idea what. If I leave $params empty it throws an error:
PHP Fatal error:  Uncaught SoapFault exception: [soap:Server] System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.ArgumentNullException: Value cannot be null etc and it highlights the line $result=

I just cannot work out what to put for $params so that I can capture all the xml data.

I've been back to krier.fr and asked for help/examples and been told they can't help.
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

There's probably a way around this dilemma, and the first thing you should ask krier.fr if they offer a RESTful interface to the data set.  A RESTful API is much easier to use because it simply responds with useful data and does not force you to guess what is going on in the other server.  This is one of the main reasons that most major internet companies abandoned SOAP about a decade ago, and almost nobody uses SOAP any more.

If they offer a RESTful API, you're (almost) home free.

If they don't then we have a little more work to do.  It would be helpful to see a true and complete example of the SOAP string posted above, but hopefully this will help you get started.
https://iconoun.com/demo/temp_fionafenton.php
<?php // demo/temp_fionafenton.php
/**
 * https://www.experts-exchange.com/questions/28974256/PHP-and-SOAP-Woes.html
 */
ini_set('display_errors', TRUE);
error_reporting(E_ALL);
echo '<pre>';

// THE SOAP RESPONSE STRING SAMPLE FROM E-E
$soap = <<<EOS
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetXmlDataResponse xmlns="http://tempuri.org/">
<GetXmlDataResult>
<lots>

<lot>
THIS IS FROM LOT #1
</lot>

<lot>
THIS IS FROM LOT #2
</lot>

</lots>
</GetXmlDataResult>
</GetXmlDataResponse>
</soap:Body>
</soap:Envelope>
EOS;

// MUNG THE SOAP RESPONSE SO WE CAN PARSE IT EASILY
$mung = mungXML($soap);

// PARSE THE XML DOCUMENT
$objs = SimpleXML_Load_String($mung);
$lots = $objs->soap_Body->GetXmlDataResponse->GetXmlDataResult->lots;

// USE AN ITERATOR TO ACCESS THE DATA INSIDE THE OBJECT
foreach ($lots->lot as $thing)
{
    echo PHP_EOL . trim($thing);
}


// A FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE
function mungXML($xml)
{
    $obj = SimpleXML_Load_String($xml);
    if ($obj === FALSE) return $xml;

    // GET NAMESPACES, IF ANY
    $nss = $obj->getNamespaces(TRUE);
    if (empty($nss)) return $xml;

    // CHANGE ns: INTO ns_
    $nsm = array_keys($nss);
    foreach ($nsm as $key)
    {
        // A REGULAR EXPRESSION TO MUNG THE XML
        $rgx
        = '#'               // REGEX DELIMITER
        . '('               // GROUP PATTERN 1
        . '\<'              // LOCATE A LEFT WICKET
        . '/?'              // MAYBE FOLLOWED BY A SLASH
        . preg_quote($key)  // THE NAMESPACE
        . ')'               // END GROUP PATTERN
        . '('               // GROUP PATTERN 2
        . ':{1}'            // A COLON (EXACTLY ONE)
        . ')'               // END GROUP PATTERN
        . '#'               // REGEX DELIMITER
        ;
        // INSERT THE UNDERSCORE INTO THE TAG NAME
        $rep
        = '$1'          // BACKREFERENCE TO GROUP 1
        . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
        ;
        // PERFORM THE REPLACEMENT
        $xml =  preg_replace($rgx, $rep, $xml);
    }
    return $xml;
}

Open in new window

Outputs:
THIS IS FROM LOT #1
THIS IS FROM LOT #2

Open in new window

Avatar of fionafenton

ASKER

Hi Ray
Having seen your comments in other questions I have already asked them if there is a REST alternative but have yet to hear back from them.

I'm not sure that you've fully understood my problem? It is getting the soap response that I'm having trouble with. Once I've got it and saved it I can parse it. At the moment I can only get the response by going to soapclient.com web page above and manually entering login credentials and then copying and pasting the output.
What I want to eventually do is set up a cron to do it.  I should be able to achieve this using
$client = new SoapClient("http://alize.krier.fr/AlizeWS/ExportXmlWs.asmx?wsdl", array('loginAnnonceur' => "xxxxxx",
                                            'motDePasseAnnonceur'    => "xxxxxx",
                                            'codeAgence' => "xxxxxx",
					    'trace' => 1));
$params=array();
$result = $client->GetXmlData($params);

Open in new window

If I could just work out what value(s) to give to $params.

(Each lot element has over 100 sub elements which I why I didn't bother listing them all)
Hi, Fiona.  I can't make them respond in a timely manner but I may be able to help you while we wait for common sense to prevail!

E-E has quirky rules about direct communications, so please bear with me as we try to work together...

Please go to this page and open the "Full Biography" tab
https://www.experts-exchange.com/members/Ray_Paseur.html

Then get my email address from the information there.

Then send me the credentials you've used to get the the response information from the soapclient.com web site.  I need the complete URL(s) and any login credentials you've used to get the browser to "login" to the site.

I believe that we can read this site in an automated manner and parse the response.  This is not the ultimate and ideal solution but it will buy you time until you can get the krier.fr  people to respond to your request for help.  Worth a try, at least.
Thanks Ray. Have sent email.
ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Brilliant! Thank you so much Ray. I would never have got that on my own.

Now that I can grab the data I can parse it and extract what I need.
Gr8! :-)