PHP SOAP Message creation from stdClass Object - php

So I have soap connection to some services. The App I'm creating is fully object oriented. The data for messages I'm sending are therefore in PHP in stdClass objects (it is extended by my Classes - representants of data in future xml document with predeclared public $variables). Everything is fine as long as I have to create documents like:
<Request>
<paramsList>
<someParam></someParam>
<someParam></someParam>
<someParam></someParam>
<someParam></someParam>
</paramsList>
<moreData></moreData>
</Request>
Now the problem is to create structure like:
<Request>
<paramsList>
<someParam id="3"></someParam>
<someParam id="4"></someParam>
<someParam id="18"></someParam>
<someParam id="512"></someParam>
</paramsList>
<moreData isImportant="false"></moreData>
</Request>
Is it possible (and if - how?) to add these things to stdObject so I don't have to change execution of SOAP functions from this simple form:
$client->functionToExecute($stdObjectOrientedData);
Example object and usage:
class Request extends \stdClass
{
public $paramsList;
public $moreData;
}
$objectToSend = new \stdObject();
$request = new Request();
$request->paramsList = $someParamsObjectsArray;
$request->moreData = $someData;
$objectToSend->Request = $request;
$client->functionToExecute($objectToSend);

In case someone visit this question, here is the answer.
If WSDL file is created properly, PHP will generate response with using normal StdClass objects. just name properties as they are named in request.
If WSDL has errors, only thing you can do is to make requests manualy from templates.

Related

How to globally override the SoapClient class?

I use external libraries to communicate with external systems. Communication is via Soap.
I provide the library with a set of data in a simple way. She checks the data, sends the request, and receives the reply. Converts the response to its object and returns.
How can I access the SoapClient object without making changes to the external library?
For this object, I need the original data. Request, response, headers.
Is it possible to do?
EDIT:
A simple example of using one of the many external libraries:
class fedex {
public function trackShipment($number)
{
$trackRequest = new TrackServiceTrackRequest();
$trackRequest->WebAuthenticationDetail->UserCredential->Key = $this->getAccessNumber();
$trackRequest->WebAuthenticationDetail->UserCredential->Password = $this->getAccountPassword();
$trackRequest->ClientDetail->AccountNumber = $this->getAccountNumber();
$trackRequest->ClientDetail->MeterNumber = $this->getMeterNumber();
$trackRequest->SelectionDetails[0]->PackageIdentifier->Value = $number;
$request = new TrackServiceRequest();
return $request->getTrackReply($trackRequest);
}
}
$fedex = new fedex();
$result = $fedex->trackShipment('123456789');
How to get original xml with request and header that was sent by library without modifying it?
The TrackServiceRequest() object does not access the SoapClient() object.

Call SOAP API using php

I have one WSDL file. file url is given below
http://home.nutselect.nl/services/DossierService.svc?wsdl
I need to get the order details from this wsdl file. but when call this soap WSDL file i got the empty window only.
Any one please help me. How to get the Order details from this soap WSDL file.
try {
$client = new SoapClient('http://home.nutselect.nl/services/DossierService.svc?wsdl');
$response = $client->Request();
print_r($response);
Saravana all you need to do is generate a php class form the wsdl. and when you inherit the class you can probably get the public methods.
Check this link for the php class generator
https://github.com/wsdl2phpgenerator/wsdl2phpgenerator

Zend Soap Server / WSDL

I've been working on a project (which I'll keep specific details out of this post with randomized data) that involves integrating our system (PHP 5.3.x+) with an API (they provided a SDK) of a major company. They provided a WSDL and claimed ours needed to match their methods and they provided examples of how output (XML generated by the Soap Server) should look.
Right now, everything has been working as expected. When I send a XML request from SoapUI (an app I'm using to test) it all processes properly and such, but the XML output isn't matching closely with their examples and we believe they said we must be close to their examples.
Basically, we created an agnostic class we initialize with a service name and it initializes into a non-agnostic class which is used via the following:
/**
* The following is used to process Soap Server based on config and any optional settings.
*
* #param string $className
* #param array $options
* #param object $config
* #return Zend_Soap_Server
*/
public static function init($className, Array $options = null, $config = null)
{
// Used to define the class and return object.
$soap_server = new Zend_Soap_Server(null, $options);
$soap_server->setClass($className, null, (isset($config) ? $config : null));
$soap_server->handle();
exit;
}
The problem itself lies within the outputted response. How would you guys suggest we build the XML output if they're very specific about everything?
1.) One of our methods is moneyTransferRequest. When I send the XML over for this, it does find the method and processes it. However, they want it to show the method name, in the response, as moneyTransferResponse but it outputs moneyTransferRequestResponse.
2.) Our output (for variables and such sent back as an object) has multiple variables, we'll say $money for example. The field for this would return as:
<money xsi:type="xsd:string">10.0</money>
They would like it to be:
<ns1:money xsi:type="xsd:string">10.0</money>
in the return.
I appreciate any help and input on the subject.
The key feature of SOAP is that it uses XML, and XML can come in a bunch of different styles but still mean the same.
I think (but I can only guess because you didn't provide details) that your two issues might be non-existing.
1.) The name of the response XML structure should align with the name mentioned in the WSDL. YOU are publishing the WSDL, so you should check if these two match. Note that the important entry point is the SOAP method - everything thereafter is defined in the WSDL itself, any consuming client should be able to figure it out as long as the names mentioned are correctly used.
2.) This is basically the same, but even easier: XML allows to use namespaces, and these can be defined in several locations, with the result being not literally the same, but every XML parser will understand that they are the same. So you should check whether the namespace that is required as "ns1" is mentioned in the XML header of your response. Every XML document has a base namespace, which does not need to be repeated on every element that belongs to it.
This is the case with the <money> element. Your style of writing uses that base namespace, their style of writing uses a namespace shortcut ns1 also introduced in the XML header, but not declared as the base namespace. So as long as there are traces of the correct XML namespace in both responses, I'd assume they are equivalent.
And the bad news would be that you cannot change how the PHP SoapServer generates the XML. You'd need to create your own implementation of a SOAP server, which I'd say is a complete waste of resources.

WCF - "Incomplete" WSDL with reference to another WSDL

I am using SoapClient to send some data from a PHP site to a .Net WCF service.
This is my (shortened for clarity) code:
$wsdl = '/var/www/libraries/MyWsdl.xml';
$myClient = new SoapClient($wsdl);
and later, the actual call:
try {
$res = $myClient->Foo($someParameter);
}
catch(SoapFault $e){
//...
}
catch(Exception $e){
//...
}
This works great when everything is online, and the error handling works if the destination server is down on the time Foo is called.
Problem is that the SoapClient constructor fails, if the destination server is down, even though i've provided it with a static XML file with the WSDL (in oppose to a URL like "http://www.destination.com/MyService?wsdl").
I believe this is happening because the WSDL contains a reference to another WSDL:
<wsdl:import namespace="http://MyCompany.Services" location="http://www.destination.com/MyService?wsdl=wsdl0"/>
This other WSDL contains the definitions of the call parameters.
So, how can I "Inline" the second "sub-WSDL" inside the original one?
Will this allow me to create a SoapClient without initiating a connection to the destination server?
This is my service definition:
[ServiceContract(Namespace = "http://MyCompany.Services")]
public interface IMyService
{
[OperationContract]
[XmlSerializerFormat(Style = OperationFormatStyle.Rpc, Use = OperationFormatUse.Literal)]
string Foo(string myParameter);
}
You can use the single WSDL-file extension from here: http://wcfextras.codeplex.com/
Note that when using .net4.5 there should be no need for it, as the default metadata endpoint now also generates single WSDL-files in addition to the linked versions.
To do that simply add "?singleWSDL” to the URI (source: http://msdn.microsoft.com/en-us/library/dd456789(v=vs.110).aspx)

using functions from internal SOAP interface via php

I received a manual to internal SOAP interface of my partner. It says:
MyPARTNER web services are provided in the form of a SOAP interface. The service is available in this URL: https://justsomeurl.com:435/soap
then some bla bla about authorization etc. and then a part about Accessible Methods:
pull()
The PULL method is used for pulling data from the database. The method
receives a unique data based parameter under an internal name
requestXML. This parameter contains data in a structured XML format.
String pull(String requestXML)
The XML contains data required to make the request, and the response
data is sent back.
then some other methods, error codes, it's not important here...
The problem is that I'm totally unexperienced in SOAP so I don't know how to use this interface via PHP. I've tried to find some examples, tutorials and I am now little bit more informed about SOAP and its functionality but still haven't found any advice about how to use interface like this...
thanx for any help
Php comes with PHP SOAP libraries, that usually are included and enabled after a common php installation.
Yuo are asked to biuld the client part of the webservice pattern. Your partner should provide you the .wsdl of the web service. The wsdl describes the avialble method, the parameters they need and what they return.
Tipically parameters and return values are array structures
This could be a skeleton for your code:
//build a client for the service
$client = new SoapClient("partner.wsdl");
//$client is now a sort of object where you can call functions
//prepare the xml parameter
$requestXML = array("parameter" => "<xml>Hello</xml>");
//call the pull function this is like
$result = $client->__soapCall("pull", $requestXML );
//print the value returned by the web service
print_r($result);
Here follows a non-wsdl example
First the location paramater is the address the SOAP request will be sent to.
The uri parameter is the target namespace of the SOAP service. This is related to xml namespaces.
A sample code for you could be:
//for URI specification you should watch your partners documentation. maybe also a fake uri (like mine) could work
//build a client for the service
$client = new SoapClient(null, array(
'location' =>
"https://justsomeurl.com:435/soap",
'uri' => "urn:WebServices",
'trace' => 1 ));
// Once built a non-wsdl web service works as a wsdl one
//$client is now a sort of object where you can call functions
//prepare the xml parameter
$requestXML = array("parameter" => "<xml>Hello</xml>");
//call the pull function this is like
$result = $client->__soapCall("pull", $requestXML );
//print the value returned by the web service
print_r($result);
Here a useful link: http://www.herongyang.com/PHP/SOAP-Use-SOAP-Extension-in-non-WSDL-Mode.html

Categories