'Parsing WSDL: coudln't load from URL only for my current URL in SOAPCLIENT?
I am using SOAPclient in PHP for my integration but after so many tries and so many efforts I am not able to achieve what I was supposed to,
Actually I am integrating a banking SOAP request which contains some authentication for initiating it but I am getting this error over and over. i.e.
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://ibluatapig.indusind.com/app/uat/DomesticPayService1.wsdl' : failed to load external entity "https://ibluatapig.indusind.com/app/uat/DomesticPayService1.wsdl"
I am just doing simple stuff which is
$soapClient = new SoapClient($url);
And after doing this I am getting error above shown but when I do the same with any other SOAP URLs I get the SOAP object and from that I can get data accordingly now I am confused why this is happening. Is this URL inappropriate or because it is banking soapApi so it require headers info which I have to pass but according to PHP docs firstly we create soapclient object then we have an option
$soapclient->__setSoapHeaders();
All method, all attempts like send $options array and send headers everything I could research I have tried but failed
I have tried these so far
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient',
),
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
],
);
$context = stream_context_create($opts);
$soapClientOptions = array(
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_MEMORY,
);
And these headers are required
$headers = array(
'SOAPAction' => 'http://tempuri.org/IDomesticPayService/GetAccBalance',
'Content-type' => 'content-type: text/xml',
'X-IBM-Client-Secret' => 'client-secret',
'X-IBM-Client-ID' => 'client-id',
);
Solution 1:[1]
Firstly, let's understand what's happening here. When you create a SoapClient
object, you need to specify some details about the SOAP service to connect to. These are normally provided in a configuration file provided by the service, in a format called WSDL. The URL you're passing to the constructor is the URL of that configuration file.
The important thing to understand here is that fetching the WSDL is not a SOAP request, it's just a normal HTTP GET request, like you'd make with a web browser, or curl. So SOAP-specific concepts like "SOAP headers" are irrelevant, and there is no "SOAP Action" to specify yet (that's part of what is configured by the WSDL once it's been fetched).
In your Postman request, you are providing two custom HTTP headers, 'X-IBM-Client-Secret' and 'X-IBM-Client-ID', which apparently are needed to access this URL. Nowhere in the PHP code you show have you attempted to pass those headers, so that's what you need to fix.
The SoapClient constructor takes a large number of options, which aren't very consistent or intuitive, but I have just rewritten the manual page to document them all. The one that's relevant here is stream_context
, which lets you set various things to include on all HTTP requests, which I believe includes fetching the initial WSDL file. Among those is the an 'http' context option called 'header', which despite its name lets you set any number of HTTP headers.
// Headers are specified as an array of strings, not key-value pairs
$headers = [
'X-IBM-Client-ID: ' . $yourIdHere,
'X-IBM-Client-Secret: ' . $yourSecretHere
];
// You can add any other context options you need in here
$contextOptions = [
'http' => [
'header' => $headers
]
];
$context = stream_context_create($contextOptions);
// You can add other SoapClient options in here
$soapClientOptions = [
'stream_context' => $context
];
// Now you can create your SOAP client
$soapClient = new SoapClient($wsdlUrl, $soapClientOptions);
If this doesn't work, you can fetch the WSDL file separately - remembering to send those custom authorization headers - and then pass a local filename where you've saved it to the SoapClient constructor. For instance, the stream_context can also be used with file_get_contents
, as long as you have the allow_url_fopen
option enabled; so you could do this:
// Headers are specified as an array of strings, not key-value pairs
$headers = [
'X-IBM-Client-ID: ' . $yourIdHere,
'X-IBM-Client-Secret: ' . $yourSecretHere
];
// You can add any other context options you need in here
$contextOptions = [
'http' => [
'header' => $headers
]
];
$context = stream_context_create($contextOptions);
// Fetch the WSDL file
$wsdlContent = file_get_contents($wsdlUrl, false, $context);
// Save it somewhere temporary
$tempWsdlFile = tempnam(sys_get_temp_dir(), 'temp-wsdl-');
file_put_content($tempWsdlFile, $wsdlContent);
// You probably want to use the extra headers in SOAP calls as well
$soapClientOptions = [
'stream_context' => $context
];
// Now you can create your SOAP client
$soapClient = new SoapClient($tempWsdlFile, $soapClientOptions);
// Clean up
unlink($tempWsdlFile);
A similar thing could be done with curl, or Guzzle, or any other HTTP library - just look for an example of setting custom HTTP headers. (Remember that you don't need anything specific to SOAP or WSDL for this step, you're just making an HTTP GET request.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |