I'm Using PHP Soap Client function to connect Remote service using this code
try
{
$result = $soapClient->GetData($parameters);
}
catch (SoapFault $fault)
{
echo "Fault code: {$fault->faultcode}" . NEWLINE;
echo "Fault string: {$fault->faultstring}" . NEWLINE;
if ($soapClient != null)
{
$soapClient = null;
}
exit();
}
$soapClient = null;
Finally I'm calling this function,
echo "Return value: {$result->GetDataResult}" . NEWLINE;
But It's not working for me and got warning message like this.
Notice: Undefined property: stdClass::$GetDataResult
You are ASSUMING that the response comes as an object with the property "GetDataResult". What makes you think so? This is not the case, and that's why you get this error message.
Dump the content of $result to see what you really get. You can also look at the WSDL file to see what the service promises to respond with.
Related
I am playing with try - catch block:
<?php
try {
$str = "http://rejstrik-firem.kurzy.cz/73631604";
$domOb = new DOMDocument();
$html = $domOb->loadHTMLFile($str);
$domOb->preserveWhiteSpace = false;
$container = $domOb->getElementById('ormaininfotab');
echo $container; // <========= this is intended error which I want catch
}
catch (Exception $e) {
echo "Exception" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
}
catch (Error $e) {
echo "Error" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
}
?>
My result is this:
Catchable fatal error: Object of class DOMElement could not be
converted to string in /var/www/html/cirkve_ares/test.php on line 8
Why is not this error catched by second catch?
As user2782001 mentioned this is not a bug in the eyes of PHP dev's. They even noted that these type of errors should be referenced as 'recoverable':
we should get rid of any references to "catchable" fatal errors (if they still exist) in favor of "recoverable" fatal errors. Using "catchable" here is confusing as they cannot be caught using catch blocks.
On the ErrorException manual page there is a neat workaround converting those "catchable/recoverable" errors to ErrorException.
<?php
function exception_error_handler($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) {
// This error code is not included in error_reporting
return;
}
throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");
?>
now you will be able to catch those errors with:
<?php
try {
// Error code
} catch (Error $e) { // this will catch only Errors
echo $e->getMessage();
}
?>
or
try {
// Error code
} catch (Throwable $t) { // this will catch both Errors and Exceptions
echo $t->getMessage();
}
?>
Someone reported this as a bug to PHP's devs, who promptly decided it was not a bug. https://bugs.php.net/bug.php?id=72948&edit=3
This case has been intentionally omitted ...(in practice you can simply convert the recoverable fatal to an exception using an error handler...)
So you still have to use the
set_error_handler()
function, which we were all hoping to leave behind. PHP's devs are so good at never letting your day be too sunny...
There might be some fatal errors which are not even caught by set_error_handler() or \Throwable.
The below implementation will catch the errors which are not even caught by \Throwable as tested in php 7.1. It should only be implemented in your development environment(by just adding it in your development config file) and shouldn't be done in production.
Implementation
register_shutdown_function(function () {
$err = error_get_last();
if (! is_null($err)) {
print 'Error#'.$err['message'].'<br>';
print 'Line#'.$err['line'].'<br>';
print 'File#'.$err['file'].'<br>';
}
});
Example Error
Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php
It has been "fixed" as of PHP 7.4 according with Manual PHP, now it throws exception:
Existing recoverable fatal errors in string conversions have been converted to Error exceptions.
I'm trying to consume a soap web service using nusoap and PHP 5.6.25 but I am having some errors. Here is the php code:
require_once 'nusoap-0.9.5/lib/nusoap.php';
$client = new nusoap_client('http://www.webservicex.net/ConvertTemperature.asmx?WSDL');
if($client->getError()){
echo 'Error';
} else {
echo 'nusoap is working';
}
Error:
Fatal error: Call to undefined function nusoap_client()
If you check any example on the internet about nusoap_client you can see that it looks like this:
$client = new nusoap_client("food.wsdl", true);
$error = $client->getError();
So when you create a new instances of class nusoap_client you need to add the word new before. So your code will look like this:
$client = new nusoap_client('http://www.webservicex.net/ConvertTemperature.asmx?WSDL');
if($client->getError()){
echo 'Error';
} else {
echo 'nusoap is working';
}
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
I am setting up Twilio and trying to send a simpe sms to my personal phone. but all i get is this error in title + this happens on Services/Twilio/Resource.php on line 127:
public function __toString() {
$out = array();
foreach ($this as $key => $value) {
if ($key !== "client" && $key !== "subresources") {
$out[$key] = (string)$value; <----------------HERE
}
}
return json_encode($out);
}
My code on controller look like this:
$client = new Services_Twilio($AccountSid, $AuthToken);
try {
foreach($listUsers as $user){
$sms = $client->account->sms_messages->create(
$phone, // From this number
$user['phone'], // To this number
$message
);
}
$data['results'] = "success";
$data['message'] = "Your message have been sent successfully";
echo json_encode($data);
} catch (Services_Twilio_RestException $e) {
$data['results'] = "error";
$data['message'] = $e->getMessage();
echo json_encode($data);
}
I am sitting for hours now, can't seem to figure out the problem. Maybe some one have used this Twilio and could give me a hint atleast where to look..
Whole error:
PHP Catchable fatal error: Object of class Services_Twilio_TinyHttp could not be converted to string in ../Services/Twilio/Resource.php on line 127, referer:
Errors are not Exceptions, they are not thrown and cannot be catched. Errors can be handled by error handlers registered with set_error_handler. Now, there are several fatal error types like E_ERROR or E_CORE_ERROR, which cannot be handled by any error handler; these errors are fatal and stop script execution, period (or full stop if you prefer ;)). But there's also an E_RECOVERABLE_ERROR, which is described as such:
Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.
http://www.php.net/manual/en/errorfunc.constants.php
So you could handle these errors with a custom error handler. You should mostly do that to possibly write custom error logs or send alert mails, but you should nonetheless terminate the script afterwards (though you are not forced to). It's just being described as a "catchable error", though it has nothing to do with try..catch.
The cause of the error in your case is that you're trying to cast an object to a string, but the object doesn't like that. You should look at the documentation for the class how the object wants to be treated and how you can get the data you want out of it. (string) does not work, plain and simple.
You should be able to convert any of the resources, eg $client->account, $message = $client->account->messages->get('MM123') to a string, by calling echo on it or similar.
It looks like somewhere you are trying to cast the http client ($client->http) to a string. The http client doesn't define a tostring method.
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';
}