Soap Function Not Found - php

So I am trying to connect using SoapClient but am running into issues.
$this->client = new SoapClient(self::parser_url . '/SovrenConvertAndParse/ConvertAndParse.asmx?WSDL',array('soap_version' => SOAP_1_2
));
var_dump($this->client);
var_dump($this->client->__getFunctions());
try { var_dump($this->client->GetVersionInfo());}
catch (Exception $e){echo $e->getMessage();}
And here are the results I get:
object(SoapClient)#32 (2) {
["_soap_version"]=>
int(2)
["sdl"]=>
resource(42) of type (Unknown)
}
array(30) {
...
[18]=>
string(65) "GetVersionInfoResponse GetVersionInfo(GetVersionInfo $parameters)"
...
}
Not Found
Seems like if the function shows up in getFunctions() then I should be able to call it, and it should be findable. No? What could cause something like this?
So I also tried it without the try/catch and I get the following error:
Fatal error: Uncaught SoapFault exception: [HTTP] Not Found in /path/to/file:29
Anyone have any ideas as to what could be going on and how to fix this?

I'm from Sovren and I just stumbled across this post. Since you didn't contact us for support I'll assume you've already resolved this problem. But for other readers, I've run the following file with PHP 5.2.12 and the call to GetVersionInfo responded correctly with both SOAP_1_1 and SOAP_1_2:
<?php
$client = new SoapClient(
'http://localhost/SovrenConvertAndParse/ConvertAndParse.asmx?WSDL',
array('soap_version' => SOAP_1_2));
var_dump($client);
var_dump($client->__getFunctions());
try { var_dump($client->GetVersionInfo());}
catch (Exception $e){echo $e->getMessage();}
?>

this should work ..
$this->client = new SoapClient(self::parser_url . '/SovrenConvertAndParse/ConvertAndParse.asmx?WSDL',array("soap_version" => SOAP_1_1
));
var_dump($this->client);
var_dump($this->client->__getFunctions());
try { var_dump($this->client->GetVersionInfo(GetVersionInfoResult=>"version"));} //this is where i am editing your question, you need to have a parameter passed
catch (Exception $e){echo $e->getMessage();}

Related

PHP Cannot Run Soap Function from wsdl file

Hi am trying to run a function from wsdl. How to run this function?
When i am running get functions i am getting this
array(3) { [0]=> string(797) "ClientSoap createClient(string $client_name, string $client_password, string $first_name, string $last_name)" }
I want to run the createClient function .
I already tried using this code
$client = new SoapClient('mywsdl.wsdl');
$data = $client->createClient("samplecustomer", "samplepass", "first", "last");
print_r($data);
I am getting an error that createClient does not exist. Any ides?
Thanks in advance
I don't know if that can help you but you can add a try catch surround the declaration.
try {
$soapClient = new \SoapClient($url. '?wsdl', $options);
} catch (\SoapFault $e) {
print_r($e->getMessage();
}

PHP SOAP Second request doesn't throw an exception

i am trying to connect to a webservice. My webserviceHelper is:
class webserviceHelper {
public function __construct($params) {
$this->service_url = $params['service_url'];
try {
$this->soap = new SoapClient($this->service_url,
array('exceptions' => true));
}
catch (SoapFault $exc) {
echo 'SoapFault<br />';
die;
}
catch (Exception $exc) {
echo 'Exception<br />';
die;
}
}
...
}
When the service is down, i make a request to the page where the webserviceHelper object created. Before the response i make second request to the same page. At first one, i got "soapFault" as output but at the second, i got a fatal error.
Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'WebService?wsdl' : failed to load external entity "WebService?wsdl" in webserviceHelper.php on line 40
How can i prevent this error?
use error_get_last() after $this->soap = new SoapClient(..... to get potential errors
I handled it by using a hook in codeigniter. Thanks to the blogger. How To Catch PHP Fatal Error In CodeIgniter

ZendSoapServer looses Error Code when throwing an Exception / SoapFault

I have a Zend Backend & a Zend Frontend, both communicating over SOAP. An Exception on the backend, should throw an Exception / SoapFault on the Frontend. This works with the Error-Message, but the Error-Code gets lost somehow. I need the code to be able to show errors in different languages on the frontend. I tried a lot, but couldnt get it to work.
This is the Backend handleSoap function of my SoapController:
private function handleSOAP($class) {
$options = array('uri' => 'urn:'.$class.'','location' => $this->_WSDL_URI);
$server = new Zend_Soap_Server(null, $options);
$server->setEncoding('ISO-8859-1');
$server->setClass($class);
$server->registerFaultException('Exception');
$server->handle();
}
On the Frontend the SoapCallerClass:
public function __construct() {
$this->client = new Zend_Soap_Client($this->_WSDL_URI);
$this->client->setWsdlCache(WSDL_CACHE_NONE);
$this->client->setEncoding('ISO-8859-1');
}
public function __call($method,$params) {
try {
$this->client->mySoapFunction();
} catch (Exception $e) {
throw $e; // No error code inside !
}
}
I looked at the SoapFault object passed to the Frontend. Using getMessage() returns the original message. Using getCode returns 0, but the object has a property called faultcode and faultmessage that contain the original code & message of the exception.

PHP SOAP error catching

I'm getting desperate, all I want is simple error handling when the PHP SOAP Web Service is down to echo an error message login service down. Please help me!
At the moment it's still displaying the error (along with warnings...):
Fatal error: SOAP-ERROR: Parsing WSDL
Here is the script:
<?php
session_start();
$login="0000000000000nhfidsj"; //It is like this for testing, It will be changed to a GET
$username = substr($login,0,13); //as password is always 13 char long
//(the validation is done int he javascript)
$password = substr($login,13);
try
{
ini_set('default_socket_timeout', 5); //So time out is 5 seconds
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl"); //locally hosted
$array = $client->login(array('username'=>$username,
'password'=>$password));
$result = $array->return;
}catch(SoapFault $client){
$result = "0";
}
if($result == "true")//as this would be what the ws returns if login success
{
$_SESSION['user'] = $login;
echo "00";
}
else
{
echo "01 error: login failed";
}
?>
UPDATE July 2018
If you don't care about getting the SoapFault details and just want to catch any errors coming from the SoapClient you can catch "Throwable" in PHP 7+. The original problem was that SoapClient can "Fatal Error" before it throws a SoapFault so by catching both errors and exceptions with Throwable you will have very simple error handling e.g.
try{
soap connection...
}catch(Throwable $e){
echo 'sorry... our service is down';
}
If you need to catch the SoapFault specifically, try the original answer which should allow you to suppress the fatal error that prevents the SoapFault being thrown
Original answer relevant for older PHP versions
SOAP can fatal error calling the native php functions internally which prevents the SoapFaults being thrown so we need to log and suppress those native errors.
First you need to turn on exceptions handling:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
} catch ( SoapFault $e ) { // Do NOT try and catch "Exception" here
echo 'sorry... our service is down';
}
AND THEN you also need to silently suppress any "PHP errors" that originate from SOAP using a custom error handler:
set_error_handler('handlePhpErrors');
function handlePhpErrors($errno, $errmsg, $filename, $linenum, $vars) {
if (stristr($errmsg, "SoapClient::SoapClient")) {
error_log($errmsg); // silently log error
return; // skip error handling
}
}
You will then find it now instead trips a SoapFault exception with the correct message "Soap error: SOAP-ERROR: Parsing WSDL: Couldn't load from '...'" and so you end up back in your catch statement able to handle the error more effectively.
Fatal error: SOAP-ERROR: Parsing WSDL Means the WSDL is wrong and maybe missing? so it's not related to soap. And you cannot handle FATAL ERROR with a try catch. See this link : http://ru2.php.net/set_error_handler#35622
What do you get when you try to access http://192.168.0.142:8080/services/Logon?wsdl in your browser?
You can check if the WSDL is present like this
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
/* You don't have a WSDL Service is down. exit the function */
}
curl_close($handle);
/* Do your stuff with SOAP here. */
Unfortunately SOAP throws a fatal error when the service is down / unreachable rather than returning a SoapFault object.
That being said, you can set it to throw an exception. You probably omitted the part where you're setting the exceptions soap_client option to false
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => false, // change to true so it will throw an exception
));
Catch the exception when service is down:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
}
catch ( Exception $e )
{
echo 'sorry... our service is down';
}
Perhaps a better alternative:
set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');
function my_exception_handler($e) {
exit('Error, something went terribly wrong: '.$e);
}
function my_error_handler($no,$str,$file,$line) {
$e = new ErrorException($str,$no,0,$file,$line);
my_exception_handler($e);
}
Where you can adjust error messages in the mentioned functions.
I use it to return a message in the same situation you do, as it can occur at any time.
Say you send a soap message after the initial login, and that response never arrives or arrives only partially, this way you can return a message without any script paths, names and linenumbers.
In such cases I do not return $e at all, instead I just output something like: 'Something went wrong, please try it again (later).'
I ended up handling it this way:
libxml_use_internal_errors(true);
$sxe = simplexml_load_string(file_get_contents($url));
if (!$sxe) {
return [
'error' => true,
'info' => 'WSDL does not return valid xml',
];
}
libxml_use_internal_errors(false);
Do your soap call after this check.
Everything turned out to be much more trivial - when using namespaces, be sure to specify the root ns!
Those catch (SoapFailt $fault) - is wrong, right way catch (\SoapFault $fault)
SoapFault doesn't extends Exception, catch the especific type works:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
}
catch ( SoapFault $e )
{
echo 'sorry... our service is down';
}

PHP SoapFault not caught by exception handlers

I am new to PHP exception handling and SOAP. For some reason I cannot catch a SoapFault. I don't know why. The soap server is not mine.
try {
$contact_id = $objSoapClient->getContactIdFromVisitorId('12345');
}
catch (SoapFault $sf) {
echo "Soapfault";
}
catch (Exception $e) {
echo "Exception";
}
I am purposely passing in the bad id 12345. When I enable errors I see the following message SoapFault exception: [SOAP-ENV:Client] Invalid Visitor ID. However, my catch SoapFault block nor my catch Exception block ever get hit. Why?
The code you've submitted appears to be correct. Here's the only thing that comes to my mind.
With that said, if the code is located inside a class that define a namespace, you code will not work as it will try to reference Exception as \namespace\Exception which does not exist. "Passive" references such as those in catch clauses or instanceof expressions are permitted because the missing class could be loaded later.
For it to work, you have to prefix the class name with a slash (i.e. \Exception) to tell PHP to use PHP from the global space (or root if you want to call it that) (PHP) as opposed to your namespace;
<?php
namespace test;
class Foo
{
public function bar()
{
try
{
something_that_might_break();
}
catch (\Exception $e)
{
// this will work
}
}
}
?>
You can find lots of information about namespaces here: http://php.net/manual/en/language.namespaces.php.
The problem turned out to be my SoapClient declaration. There is an exceptions parameter that must be set in order for the exceptions to trigger.
$objSoapClient = new SoapClient('https://mywebservice.com/foo.wsdl', array(
"trace" => false,
"exceptions" => true, // <-------------- This!!!
'login' => 'username', //username
'password' => 'password', //password
'features' => SOAP_SINGLE_ELEMENT_ARRAYS + SOAP_USE_XSI_ARRAY_TYPE
));

Categories