Make and Display SOAP Request via PHP - php

I want to learn how to make a SOAP request and then post response in PHP. Here is my request code: http://pastebin.com/PBb2i0XN
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.restfulwebservices.net/ServiceContracts/2008/01">
<SOAP-ENV:Body>
<ns1:GetStockQuote>
<ns1:request>Goog</ns1:request>
</ns1:GetStockQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WSDL is http://www.restfulwebservices.net/wcf/StockQuoteService.svc?wsdl

PHP has a wrapper for SOAP. Check out http://php.net/soap. This should solve all your problems.
You first instantiate a SoapClient class using the following syntax.
$client = new SoapClient("some.wsdl");
You can then use the SoapClient::__getFunctions() method to determine the different functions your WSDL gives you.
public array SoapClient::__getFunctions ( void )
This client will enable you to call the soap functions from your WSDL as if they were PHP functions
For example in order to call the GetStockQuote method from your WSDL, all you have to do is the following.
$client = new SoapClient("http://www.restfulwebservices.net/wcf/StockQuoteService.svc?wsdl");
$client->GetStockQuote();
Also when you use the getFunctions method, you will get a list of all parameters each method in the WSDL expects.
Hope this was helpful. All the best.

Related

How does it work with the magic WSDL URI query parameter?

I'm building a Soap server within a Symfony application. As first step I created a controller with my "hello world" Soap action and defined the route for it:
routing.yml
api.soap.foo
path: /soapapi/foo
defaults: { _controller: SoapBundle\Controller\FooController:bar }
methods: [GET, HEAD, POST]
FooController#bar(...)
protected function bar(Request $request)
{
$autodiscover = new AutoDiscover();
$autodiscover
->setClass(MyFooBarService::class)
->setUri('http://my-app.loc/soapapi/foo/bar')
->setServiceName('MyFooBarService')
;
$wsdl = $autodiscover->generate();
$wsdl->dump(__DIR__ . '/soapapi-foo-bar.wsdl');
$server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl');
$server->setObject($this->myFooBarService);
$response = new Response();
$response->headers->set('Content-Type', 'text/xml; charset=ISO-8859-1');
ob_start();
$server->handle();
$response->setContent(ob_get_clean());
return $response;
}
Now, when I call http://my-app.loc/soapapi/foo/bar in a browser or using cURL (so via HTTP GET), I get an error:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Bad Request</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But when I call http://my-app.loc/soapapi/foo/bar?wsdl, I actually get the (generated) WSDL document. Why? I have not defined anywhere, that it should work like this. Why and how does this (magic) work? Is it Symfony specific magic?
This is a great question.
No this is not Symfony specific, it's a behavior of the built-in SOAP server in PHP. When the endpoint URL is accessed with ?wsdl appended, the SOAP server will respond with the wsdl document that it was instantiated with in the constructor:
$server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl');
I haven't been able to find where this behavior is documented on the PHP website, but it clearly exists and is reproducible.
The code for the feature can be found in PHP's source code starting on line 1369 and ending on line 1396. The code checks if the request method is GET and checks for the presence of a 'wsdl' query parameter.

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

How to remove SOAP namespace from call

I'm trying to connect to a WSDL webservice using PHP SOAP. Now I need to remove the SOAP elements from the XML which is send. What I have now is the following:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://service.com">
<SOAP-ENV:Body>
<ns1:Calculate>
//Content
</ns1:Calculate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
What I want is the following:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:Calculate xmlns:ns1="http://service.com">
//Content
</ns1:Calculate>
Is there any way to accomplish this? Is SOAP the one I need to send such requests?
SOAP is protocol, and if you want to SOAP request both client and server side must accept and send back requests according to this protocol.
Just check these settings :
$client = new SoapClient("some.wsdl", array('soap_version' => SOAP_1_2));
Server may uses 1_2 or 1_1 version.
And you should contact with Web Service provider to get documentation about implementation of web service.
Override SoapClient class with a customized __doRequest. The new method removes the namespace references from the XML then calls the parent's __doRequest to fulfill the request with the modified XML. A simple but effective solution.
class MySoapClient extends SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way=0)
{
$request = str_replace('ns1:', '', $request);
parent::__doRequest($request, $location, $action, $version, $one_way);
}
}
# Invoke derived class instead of base class SoapClient
$client = new MySoapClient($wsdl, $options);
If you want to make a SOAP request, these tags are required. Is it really SOAP server on your opposite trying to make request?

Switching from NuSoap to PHP5 Soap - need a jumpstart

Here's the call I'm trying to make:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:SessionHeader xmlns:urn="http://www.mywebservice.com/webservices/SoapService" xmlns="http://www.mywebservice.com/webservices/SoapService" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<urn:sessionId xmlns:urn="http://www.mywebservice.com/webservices/SoapService">LOGINTOKEN=your instance name</urn:sessionId>
</urn:SessionHeader>
</soap:Header>
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns2:login xmlns:ns2="http://www.mywebservice.com/webservices/SoapService">
<wsUser>
<entityId>0</entityId>
<password>your password</password>
<username>your username</username>
</wsUser>
</ns2:login>
</soap:Body>
But I'm having trouble finding out how to set up the custom headers in PHP5's Soap. With nuSoap I could just put the whole thing into a variable and then use $client->setHeader($headerVar) but I can't find anything similar in PHP. If I could replicate this one call, I can figure the rest out. Any help would be appreciated!
Thanks in advance!
Update: I've gone through tutorial after tutorial, and read the PHP docs, but nothing seems to work. I can do what I want with curl (as well as nuSoap) but I thought the native PHP5 Soap would be easier and possibly more stable. I guess not...
Update 2
Here's the code I'm trying:
$soapurl = 'http://www.mywebservice.com/webservices/SoapService?wsdl';
$client = new SoapClient($soapurl,array('trace'=>true));
$token = "LOGINTOKEN=your instance name";
$header = new SoapHeader('http://www.mywebservice.com/webservices/SoapService', 'SessionHeader', array('sessionId' => $token));
$client->__setSoapHeaders($header);
$client->login(array("wsUser" => array('entityId'=>'0','username'=>'my username','password'=>'my password')));
And the error I get:
**Fatal error**: Uncaught SoapFault exception: [ns1:InvalidSecurity] An error was discovered processing the <wsse:Security> header in C:\www\soap\index.php:12 Stack trace: #0 C:\www\soap\index.php(12): SoapClient->__call('login', Array) #1 C:\www\soap\index.php(12): SoapClient->login(Array) #2 {main} thrown in C:\www\soap\index.php on line 12
Update 3
So it looks like the "sessionId" is being sent as "key" with the token sent as "value".
*REQUEST*:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.mywebservice.com/webservices/SoapService">
<SOAP-ENV:Header>
<ns1:SessionHeader><item><key>sessionId</key><value>LOGINTOKEN=my token</value></item>
</ns1:SessionHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body><ns1:login><wsUser><entityId>0</entityId><password>my password</password><username>my username</username></wsUser></ns1:login></SOAP-ENV:Body></SOAP-ENV:Envelope>
Have you tried the SoapHeader class to construct your header? Would something like this work?
//Assume $token holds your login token and $client holds the SoapClient object
$header = new SoapHeader('http://www.mywebservice.com/webservices/SoapService', 'SessionHeader', array('sessionId' => $token));
$client->__setSoapHeaders($header);
That should create the header and add it to the SoapClient. Every subsequent call using the SoapClient will then have that header set. As to the exact format, I wouldn't worry too much. You sample XML uses an alias for the namespace called urn. PHP probably won't arrive at exactly the same alias but it should still work. Also I don't think that declaring the xmlns in every child element is needed. I think that a child node automatically inherits the namespace of its parent in XML, but I'm not 100% certain on that. The bottom line is that as long as the right URL's are declared in the namespaces it should be fine even if the XML doesn't exactly match your example.
One other thing you could try-have you switched on tracing in the SoapClient? This is one of the parameters that can be passed to the constructor and it enables you to view the XML SOAP requests and responses. If it still doesn't work using the SoapHeader class try switching tracing on to see what's being sent and received.

How to easily consume a web service from PHP

Is there available any tool for PHP which can be used to generate code for consuming a web service based on its WSDL? Something comparable to clicking "Add Web Reference" in Visual Studio or the Eclipse plugin which does the same thing for Java.
In PHP 5 you can use SoapClient on the WSDL to call the web service functions. For example:
$client = new SoapClient("some.wsdl");
and $client is now an object which has class methods as defined in some.wsdl. So if there was a method called getTime in the WSDL then you would just call:
$result = $client->getTime();
And the result of that would (obviously) be in the $result variable. You can use the __getFunctions method to return a list of all the available methods.
I've had great success with wsdl2php. It will automatically create wrapper classes for all objects and methods used in your web service.
I have used NuSOAP in the past. I liked it because it is just a set of PHP files that you can include. There is nothing to install on the web server and no config options to change. It has WSDL support as well which is a bonus.
This article explains how you can use PHP SoapClient to call a api web service.
Say you were provided the following:
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="http://thesite.com/">
<x:Header/>
<x:Body>
<int:authenticateLogin>
<int:LoginId>12345</int:LoginId>
</int:authenticateLogin>
</x:Body>
</x:Envelope>
and
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<authenticateLoginResponse xmlns="http://thesite.com/">
<authenticateLoginResult>
<RequestStatus>true</RequestStatus>
<UserName>003p0000006XKX3AAO</UserName>
<BearerToken>Abcdef1234567890</BearerToken>
</authenticateLoginResult>
</authenticateLoginResponse>
</s:Body>
</s:Envelope>
Let's say that accessing http://thesite.com/ said that the WSDL address is:
http://thesite.com/PortalIntegratorService.svc?wsdl
$client = new SoapClient('http://thesite.com/PortalIntegratorService.svc?wsdl');
$result = $client->authenticateLogin(array('LoginId' => 12345));
if (!empty($result->authenticateLoginResult->RequestStatus)
&& !empty($result->authenticateLoginResult->UserName)) {
echo 'The username is: '.$result->authenticateLoginResult->UserName;
}
As you can see, the items specified in the XML are used in the PHP code though the LoginId value can be changed.
Well, those features are specific to a tool that you are using for development in those languages.
You wouldn't have those tools if (for example) you were using notepad to write code. So, maybe you should ask the question for the tool you are using.
For PHP: http://webservices.xml.com/pub/a/ws/2004/03/24/phpws.html
HI I got this from this site : http://forums.asp.net/t/887892.aspx?Consume+an+ASP+NET+Web+Service+with+PHP
The web service has method Add which takes two params:
<?php
$client = new SoapClient("http://localhost/csharp/web_service.asmx?wsdl");
print_r( $client->Add(array("a" => "5", "b" =>"2")));
?>

Categories