Link to home
Start Free TrialLog in
Avatar of Neil Thompson
Neil ThompsonFlag for United Kingdom of Great Britain and Northern Ireland

asked on

PHP Soap Server returning XML but < & > as < / >

Hi I wonder if you gurus can assist please.

I have a really simply SOAP server in PHP that at present I just need to send back a valid XML string for. All works ok from the request side but my response seems to be altering the < & > to &lt; / &gt;

Here is my basic SOAP Server:
<?php 

require "functions/getProperties.function.php";

$options = array(
	'uri' => 'http://s3052/webServices/ShepwayWebService',
    'location' => 'http://s3052/webServices/ShepwayWebService.php',
    'trace' => true
);

$server = new SOAPServer(null, $options);

$server->addFunction("GetProperties");

$server->handle();

?>

Open in new window


Any my functions file:
<?php

function GetProperties($strSearch){	

	// required classes
	require_once("config.php");	
	
	$response = '<GetPropertiesResponse xmlns="http://www.mvm.co.uk/webservices/M3PP"><GetPropertiesResult><MVM xmlns="http://www.mvm.co.uk"><mvm:PUBLICPROTECTION xmlns:mvm="http://www.mvm.co.uk"><M3PPPROPERTIES xmlns="http://www.mvm.co.uk"><SUBUPRN>50028034</SUBUPRN><UKEY>PI/000025895</UKEY><ADDRESS>1 Trimworth Road, Folkestone, Kent, CT19 4EJ</ADDRESS><SEARCH>TRIMWORTH ROAD</SEARCH><BUILDING_NUMBER>1</BUILDING_NUMBER><CLOSED>N</CLOSED><OUT_OF_AREA>N</OUT_OF_AREA></M3PPPROPERTIES></mvm:PUBLICPROTECTION><RESULTS><RESULT><RESULTCODE>0</RESULTCODE><RESULTDESC>Successful</RESULTDESC></RESULT></RESULTS></MVM></GetPropertiesResult></GetPropertiesResponse>';
		
	return $response;

}

?>

Open in new window


Now, If I run a test using the following code and look at the source code it works fine:
<?php 

$pf_payload  = '<GetProperties><strSearch>Trimworth Road</strSearch><strBuilding_Number/></GetProperties>';

// make the SOAP call
$options = array(    
	'uri' => 'http://s3052/webServices/ShepwayWebService',
    'location' => 'http://s3052/webServices/ShepwayWebService.php',
	'trace' => 1
);

$stub = new SoapClient(null,$options);

try { 
	echo $stub->GetProperties($pf_payload);
} catch (SoapFault $exception) { 
	error_log("\n## SOAP call exception \n: " . $exception);       
} 

error_log("\n## request : \n" . htmlspecialchars_decode($stub->__getLastRequest()));
error_log("\n## response : \n" . htmlspecialchars_decode($stub->__getLastResponse()));

?>

Open in new window


This reply "SEEMS" correct:
[01-Mar-2017 14:30:27 Europe/London] 
## request : 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://s3052/webServices/ShepwayWebService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:GetProperties><param0 xsi:type="xsd:string"><GetProperties><strSearch>Trimworth Road</strSearch><strBuilding_Number/></GetProperties></param0></ns1:GetProperties></SOAP-ENV:Body></SOAP-ENV:Envelope>


[01-Mar-2017 14:30:27 Europe/London] 
## response : 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://s3052/webServices/ShepwayWebService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:GetPropertiesResponse><return xsi:type="xsd:string"><GetPropertiesResponse xmlns="http://www.mvm.co.uk/webservices/M3PP"><GetPropertiesResult><MVM xmlns="http://www.mvm.co.uk"><mvm:PUBLICPROTECTION xmlns:mvm="http://www.mvm.co.uk"><M3PPPROPERTIES xmlns="http://www.mvm.co.uk"><SUBUPRN>50028034</SUBUPRN><UKEY>PI/000025895</UKEY><ADDRESS>1 Trimworth Road, Folkestone, Kent, CT19 4EJ</ADDRESS><SEARCH>TRIMWORTH ROAD</SEARCH><BUILDING_NUMBER>1</BUILDING_NUMBER><CLOSED>N</CLOSED><OUT_OF_AREA>N</OUT_OF_AREA></M3PPPROPERTIES></mvm:PUBLICPROTECTION><RESULTS><RESULT><RESULTCODE>0</RESULTCODE><RESULTDESC>Successful</RESULTDESC></RESULT></RESULTS></MVM></GetPropertiesResult></GetPropertiesResponse></return></ns1:GetPropertiesResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

Open in new window


But when I call it via a SOAP test server, or the 3rd party software calling it I amends the <> giving this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://s3052/webServices/ShepwayWebService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:GetPropertiesResponse>
      <return xsi:type="xsd:string">&lt;GetPropertiesResponse&gt;&lt;GetPropertiesResult&gt;&lt;MVM&gt;&lt;PUBLICPROTECTION&gt;&lt;M3PPPROPERTIES&gt;&lt;SUBUPRN&gt;50028034&lt;/SUBUPRN&gt;&lt;UKEY&gt;PI/000025895&lt;/UKEY&gt;&lt;ADDRESS&gt;1 Trimworth Road, Folkestone, Kent, CT19 4EJ&lt;/ADDRESS&gt;&lt;SEARCH&gt;TRIMWORTH ROAD&lt;/SEARCH&gt;&lt;BUILDING_NUMBER&gt;1&lt;/BUILDING_NUMBER&gt;&lt;CLOSED&gt;N&lt;/CLOSED&gt;&lt;OUT_OF_AREA&gt;N&lt;/OUT_OF_AREA&gt;&lt;/M3PPPROPERTIES&gt;&lt;/mvm:PUBLICPROTECTION&gt;&lt;RESULTS&gt;&lt;RESULT&gt;&lt;RESULTCODE&gt;0&lt;/RESULTCODE&gt;&lt;RESULTDESC&gt;Successful&lt;/RESULTDESC&gt;&lt;/RESULT&gt;&lt;/RESULTS&gt;&lt;/MVM&gt;&lt;/GetPropertiesResult&gt;&lt;/GetPropertiesResponse&gt;</return>
    </ns1:GetPropertiesResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Open in new window


Any ideas please?
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

At first glance, this looks like expected behavior.  It looks like you are dealing with an XML document that is embedded inside an XML document.

You can't have < or > inside the data fields of an XML document.  You might want to use this function if you need to recover the wickets.
http://php.net/manual/en/function.html-entity-decode.php
Avatar of Neil Thompson

ASKER

Thanks Ray, Would it be better to use an array to push the data back then rather than my hard coded text

Something along the lines of this style (not this content)

$response = array(
                  "Result" => 'SYSTEM_ERROR',
                  "ResultDescription" => 'AppContext element '.$appContext.' is not in the approved lookup types list',
                  "AccountDescription" => '',
                  "AccountPostCode" => '',
                  "Balance" => '',
                  "MinimumPayment" => ''
                  );
It may be a bigger problem than that... let me work with this a little bit.
thank you
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
Greetings Neil Thompson , , , Building a PHP SOAP interface for remote contact (client) API call and execution is Very Very Difficult, time consuming and head banging FRUSTRATING! ! You are on the wrong path to development debugging in this SOAP, by trying to fix the XML in the -    
   <GetPropertiesResponse xmlns="http://www.mvm.co.uk/webservices/M3PP"><GetPropertiesResult><MVM xmlns="http://www.mvm.co.uk"><mvm:PUBLICPROTECTION xmlns:mvm="http://www.mvm.co.uk"><M3PPPROPERTIES xmlns="http://www.mvm.co.uk"><SUBUPRN>50028034</SUBUPRN><UKEY>PI/000025895</UKEY><ADDRESS>1 Trimworth Road, Folkestone, Kent, CT19 4EJ</ADDRESS><SEARCH>TRIMWORTH ROAD</SEARCH><BUILDING_NUMBER>1</BUILDING_NUMBER><CLOSED>N</CLOSED><OUT_OF_AREA>N</OUT_OF_AREA></M3PPPROPERTIES></mvm:PUBLICPROTECTION><RESULTS><RESULT><RESULTCODE>0</RESULTCODE><RESULTDESC>Successful</RESULTDESC></RESULT></RESULTS></MVM></GetPropertiesResult></GetPropertiesResponse>

This is NOT how the SOAP methods - like your GetProperties( ) - are set up and this tagged XML response string  is not how you Set Up a method return!

In the SOAP, it all about REMOTE access to a communicated exchange of programming API of Objects, all SOAP methods that you define like your GetProperties( ) need the Object definitions in the SOAP WXML to define the TYPE of input parameters, and the TYPE of the method response-return. But any method response with tags < or > will be changed in the RAW XML response -
    __getLastResponse( )

BUT when the method is used in the client, the string from GetProperties( ) will be converted BACK to the original string with < and >, BUT not in the RAW XML communication.

The SOAP API connection, is now out of date, and you should NOT use it, it is very difficult to understand and build a PHP SOAP, and get it to work, especially if you need alot of DataBase access for your API methods.
SOAP if NOT for single requests for the method API, it is meant to be used to do several methods and evaluate the response and then do programming branches ( IF TESTS ) and then use other API methods without breaking the API connection.

HOWEVER, with current server HTTP connection speeds, you will be better of using a REST, as RAY suggested.

IF you want to do it as SOAP, please go to one of the PHP SOAP Tutorials, and follow the instructions there carefully, like I said it is not easy
Many thanks all, I'll have a play with these and see what I can achieve.

Unfortunately I'm working stuck between 2 3rd party legacy systems and I can only change where 1 looks for the web service, not the subsequent consuming XSLT etc the system then uses afterwards (hence the need to get the data back in exactly the same way/naming that the systems currently use which is a shame)
Not really sure about what you want us to understand from your last post? ?

You ask before about -
    "use an array to push the data back then rather than my hard coded text"

As I said, the SOAP is an Object Oriented API where the developers of the Server API need to Define ALL API communication in the WSDL (Web Services Description Language) that needs to be accessed by all Clients of the Service API. In the WSDL any Objects used in the API are defined, including methods, properties and bindings. Un like PHP, that has NO TYPING for Variables, all properties (variables) MUST be defined as a TYPE, the first basic type is either simple or complex. For simple there are string type, integer type, real type, etc. And there are arrays in the complex types (and other Types). I have not ever seen any XML as you tried to use, in your <GetPropertiesResponse>  , used as a DATA transfer in a SOAP interface. It is very common to have objects with properties (key, value pairs) used for method parameters and method return types, This is usually done in PHP with Key-Value paired ARRAY, which are translated to an object Key-Value paired for the WSLD definition. So other than doing an XML string, for parameters or method return, using a Key-Value paired Array or Object is a better way to do that, wel, , , at least that's whats mostly used for method interface.
Thanks Ray, annoyingly trying to work between 2 un-tweakable legacy systems is proving to be challenging.
Regards
Neil