Basic PHP / SOAP error, can't debug - php

I'm currently having a really frustrating time with some really simple SOAP / PHP at the moment. I've spent about a week trying EVERYTHING I can think of, on multiple different servers with different versions of PHP and they all still throw the same error. Here's the code:
function test() {
$client = new SoapClient('http://xxx', array("login" => "sandbox", "password" => "password"));
print_r($client->__getFunctions());
$ap_param = array();
// it dies here. CheckServiceAvailable is a valid function returned in __getFunctions()
$result = $client->__soapcall('CheckServiceAvailable', $ap_param);
if (is_soap_fault($result)) {
trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
}
}
It faults before the error catching can capture anything. Apache logs show the same fault as below:
Fatal error: Uncaught SoapFault exception: [s:Processing error] in C:\soap.php:13 Stack trace: #0 C:\soap.php(13): SoapClient->__soapCall('CheckServiceAva...', Array) #1 C:\soap.php(23): test() #2 {main} thrown in C:\soap.php on line 13
Without being able to catch the fault I'm totally stuck as to what to do. I don't really want to try nusoap.
Any ideas?

use:
try
{
$result = $client->__soapcall('CheckServiceAvailable', $ap_param);
}
catch (SoapFault $e)
{
echo "Cannot call method CheckServiceAvailable: {$e->getMessage()}";
}

Related

PHP soapclient call error : Object reference not set to an instance of an object.

I have the asmx webservice url : http://newxilnexbackend.cloudapp.net/XilnexNewReg.asmx and i am trying to call this web service using php soapclient but i am stuck at this error (Fatal error: SOAP Fault: (faultcode: soap:Server, faultstring: Server was unable to process request. ---> Object reference not set to an instance of an object.) in C:\xampp\htdocs\wwwroot\captcha.php on line 27). i have tried everything to fix this but no solution. can anyone help me to find out that which part i am doing it wrongly.
this is my php code :
enter code here$tes = 'hi';
try{
$client = new SoapClient("http://newxilnexbackend.cloudapp.net/XilnexNewReg.asmx?WSDL");
$result = $client->RegistrationOfNewCompany(array(
$tes, $tes, $tes
));
header("Location: http://webapp.xilnex.com/");
}
catch (SoapFault $fault) {
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}}
i have also tried this way but got same error:
$result = $client->RegistrationOfNewCompany(array(
EmailAddress=>$tes,
CompanyName=>$tes,
Name=>$tes
));

PHP Soap with Crowd wsdl

I am trying to write a code for sso login with crowd in my custom php application. I trying to to do that with SOAP. I am in a early stage now and was going through the documentation of how to connect php soap with wsdl. But i seem to be stuck very deep as i dont know what should be done next.
<?php
class test {
function authenticateApplication()
{
$client = new SoapClient("http://localhost:8095/crowd/services/SecurityServer?wsdl");
$param = array('in0' => array('credential' => 'password','name' => 'app'));
$resp=$client->authenticateApplication($param);
$token = $resp->out->token;
print_r($resp);
}
}
$t= new test;
$t->authenticateApplication();
I Dont know whats wrong with this code. I have referred it online and it seems to be correct but when i am tring to run this program i am getting this error
Fatal error: Uncaught SoapFault exception: [soap:Client] The validated object is null in /var/www/html/badebade/soaptest.php:7 Stack trace: #0 /var/www/html/badebade/soaptest.php(7): SoapClient->__call('authenticateApp...', Array) #1 /var/www/html/badebade/soaptest.php(7): SoapClient->authenticateApplication(Array) #2 /var/www/html/badebade/soaptest.php(13): test->authenticateApplication() #3 {main} thrown in /var/www/html/badebade/soaptest.php on line 7
A little help will be much appreciated as this program authenticates the application in crowd wsdl and returns the token. Can someone help me to achieve it.
function Find($request) {
try {
$soapClient = new SoapClient('wsdl.wsdl', array('trace' => 1));
$results = $soapClient->authenticateApplication($request);
return $results;
}
catch(SoapFault $ex) {
print $ex->getMessage();
echo '<HR>';
print $ex->getTraceAsString();
echo '<HR>';
echo $ex->getLine();
}
}
$results = Find($params);

Exception handling problems in php

I was trying out PHP exceptions for my project. But it turns out that the exception is thrown successfully but not being caught successfully by the code I wrote.
The code:
try{
require_once(MASTER_PHP."/master_validation.php");
require_once(MASTER_PHP."/master_user.php");
require_once(MASTER_PHP."/master_db.php"); require_once(MASTER_PHP."/master_secure.php");
require_once(MASTER_PHP."/master_ui.php");
require_once(MASTER_PHP."/master_mail.php");
require_once(MASTER_PHP."/master_filehandling.php");
require_once(MASTER_PHP."/master_archive.php");
require_once(MASTER_PHP."/master_date.php");
require_once(MASTER_PHP."/master_social.php");
require_once(MASTER_PHP."/master_message.php");
require_once(MASTER_PHP."/master_gallery.php");
require_once(MASTER_PHP."/master_backup.php");
require_once(MASTER_PHP."/master_payment.php");
require_once(MASTER_PHP."/master_sms.php");
require_once(MASTER_PHP."/master_xml.php");
$filterobj=new ta_filtervalue();
$filterobj->filterrequest();
global $noecho;
if($noecho!="yes")
{
$utilityobj=new ta_utilitymaster();
$utilityobj->includeextassets();
}
}
catch (Exception $e)
{
$custerrcode=$e->getMessage();
$dbobj=new ta_dboperations();
$res=$dbobj->dbquery("SELECT * FROM ".ERROR_CODES." WHERE ".errordb_errcode."='$custerrcode' LIMIT 0,1",DB_ERROR);
$errmsg=$res[0][changesqlquote(errordb_errdesc,"")];
$errpriority=$res[0][changesqlquote(errordb_errpriority,"")];
$errcallback1=$res[0][changesqlquote(errordb_errcallback1,"")];
$errcalltext1=$res[0][changesqlquote(errordb_errcallbacktext1,"")];
$errcallback2=$res[0][changesqlquote(errordb_errcallback2,"")];
$errcalltext2=$res[0][changesqlquote(errordb_errcallbacktext2,"")];
$errtitle=$res[0][changesqlquote(errordb_errtitle,"")];
$errobj=new ta_errorhandle();
$errobj->senderror($errmsg,$custerrcode,$errpriority,$errcallback1,$errcalltext1,$errcallback2,$errcalltext2,$errtitle);
}
If the exception occurs in master_user.php (required file) it has to be caught in the file which requires it. But it does not catch the exception.
The way I throw the exception:
throw new Exception('#ta#0000000_0000000');
where the string inside is the error code.
The error message:
Fatal error: Uncaught exception 'Exception' with message '#ta#0000000_0000000' in
C:\xampp\htdocs\techahoy\securedir\phpmaster\master_user.php:19 Stack trace: #0
C:\xampp\htdocs\techahoy\login\profile.php(4): ta_userinfo->userinit() #1 {main} thrown in
C:\xampp\htdocs\techahoy\securedir\phpmaster\master_user.php on line 19
Looks like (almost) the same as in here.
require() is identical to include() except upon failure it will also produce a fatal E_COMPILE_ERROR level error. In other words, it will halt the script

Why do I get an uncaught exception in this code?

So in my code below, I'm not sure where i went wrong. Improper use of syntax, wrong use of variables? Please help!
For some reason i run this in the browser and get back
"Fatal error: Uncaught exception 'numexception' with message 'The numbers are not set' in C:\xampp\htdocs\php_testing\test.php:29 Stack trace: #0 {main} thrown in C:\xampp\htdocs\php_testing\test.php on line 29".
I don't understand where my code went wrong???
class numexception extends Exception{}
function multiply($a,$b){
echo $a*$b;
}
$var1 = 5;
//$var2 = 2; as you can see variable 2 is not set as I commented it out to test
//the exception
if(!isset($var1) or !isset($var2)){
throw new numexception("The numbers are not set");
}
try{
multiply($var1,$var2);
}
catch(numexception $e){
echo "This exception was caught:".$e->getMessage();
}
echo "The script then continues";
The throw is not in the try, so it can't be catched.
What your code is doing is like hitting someone with a golf ball, and then yelling "Fore!".

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';
}

Categories