aburany
asked on
PHP SOAP Uncaught exception - might depend on server settings?
Dear Experts,
I have a problem with a SOAP webservice written in PHP. The webservice is written by me and is used for a stock photography site to give the ability for external applications to upload images to the site.
The code worked perfectly on an old server, it works perfectly in the new dev environment but on production server with the exactly same piece of code I get the following error:
Fatal error: Uncaught SoapFault exception (...)
There shouldn't be any PHP-include errors, as if I call the PHP functions directly, they do the work well, but the same called from an external app or called through a PHP client run on the server this error is returned.
Might this happen because of different system setup or PHP settings? The php.ini, regarding SOAP related functions seem the same. Same PHP and Apache version as well. What other setting should be looked after?
Am chasing the problem in the right direction (server difference?) or this error is probably caused by something completely different?
If needed, I can post here some codes and the WSDL file as well.
Would appreciate any ideas that would come up to your mind, I'm getting pretty clueless. Thank you!
I have a problem with a SOAP webservice written in PHP. The webservice is written by me and is used for a stock photography site to give the ability for external applications to upload images to the site.
The code worked perfectly on an old server, it works perfectly in the new dev environment but on production server with the exactly same piece of code I get the following error:
Fatal error: Uncaught SoapFault exception (...)
There shouldn't be any PHP-include errors, as if I call the PHP functions directly, they do the work well, but the same called from an external app or called through a PHP client run on the server this error is returned.
Might this happen because of different system setup or PHP settings? The php.ini, regarding SOAP related functions seem the same. Same PHP and Apache version as well. What other setting should be looked after?
Am chasing the problem in the right direction (server difference?) or this error is probably caused by something completely different?
If needed, I can post here some codes and the WSDL file as well.
Would appreciate any ideas that would come up to your mind, I'm getting pretty clueless. Thank you!
Hmmm.
Do you use an auto_(ap|pre)pend_file on you dev servers? If so is this configured on the live server?
Do you use an auto_(ap|pre)pend_file on you dev servers? If so is this configured on the live server?
ASKER
Thank you for your answers!
First of all, we don't use append/prepend files. Otherwise here is a list of differences between dev and production servers I found in PHP, can this indicate you something important maybe?
On production there's eAcc also installed:
with eAccelerator v0.9.5, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
Keep Alive set to ON on dev, OFF on production
Max Requests Keep Alive: off
extra modules here:
Loaded Modules mod_info mod_rewrite mod_ssl
HTTP headers:
on dev: Connection close
on prod: Keep-Alive timeout=5, max=100
Connection Keep-Alive
session values (lifetime, gc_probabilty) are different, though I think those wouldn't make any change
SOAP settings are the same on both boxes, and are the following:
Soap Client enabled
Soap Server enabled
Directive Local Value Master Value
soap.wsdl_cache_dir /tmp /tmp
soap.wsdl_cache_enabled 1 1
soap.wsdl_cache_ttl 86400 86400
First of all, we don't use append/prepend files. Otherwise here is a list of differences between dev and production servers I found in PHP, can this indicate you something important maybe?
On production there's eAcc also installed:
with eAccelerator v0.9.5, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
Keep Alive set to ON on dev, OFF on production
Max Requests Keep Alive: off
extra modules here:
Loaded Modules mod_info mod_rewrite mod_ssl
HTTP headers:
on dev: Connection close
on prod: Keep-Alive timeout=5, max=100
Connection Keep-Alive
session values (lifetime, gc_probabilty) are different, though I think those wouldn't make any change
SOAP settings are the same on both boxes, and are the following:
Soap Client enabled
Soap Server enabled
Directive Local Value Master Value
soap.wsdl_cache_dir /tmp /tmp
soap.wsdl_cache_enabled 1 1
soap.wsdl_cache_ttl 86400 86400
What's in the exception. Can you show the FULL error. It may have nothing to do with config.
For example, file permissions, or DB access or something like that.
For example, file permissions, or DB access or something like that.
If you've got a URL we can see the error if it is too complicated, then that would be useful.
ASKER
Here is the URL where you can see the whole error message:
http://www.stockxpert.com/plugin/client_delete.php
http://www.stockxpert.com/plugin/client_delete.php
Can you show the code for __doRequest(). I would like to see the entire XML being generated and any response you may get.
ASKER
Sure, this is the client:
<?php
$client = new SoapClient("sxc.wsdl");
print_r($client->delete("p lugintest" ,"1234", "testphoto2.jpg"));
?>
and this is the server:
<?php
require_once ("common_ws.php");
function login($username, $password) {
return ws_login ($username, $password);
}
function upload($username, $password, $title, $caption, $keywords, $filename) {
return ws_upload ($username, $password, $title, $caption, $keywords, $filename);
}
function delete($username, $password, $files) {
return ws_delete ($username, $password, $files);
}
ini_set("soap.wsdl_cache_e nabled", "0"); // disabling WSDL cache
$server = new SoapServer("sxc.wsdl");
$server->addFunction("logi n");
$server->addFunction("uplo ad");
$server->addFunction("dele te");
$server->handle();
?>
<?php
$client = new SoapClient("sxc.wsdl");
print_r($client->delete("p
?>
and this is the server:
<?php
require_once ("common_ws.php");
function login($username, $password) {
return ws_login ($username, $password);
}
function upload($username, $password, $title, $caption, $keywords, $filename) {
return ws_upload ($username, $password, $title, $caption, $keywords, $filename);
}
function delete($username, $password, $files) {
return ws_delete ($username, $password, $files);
}
ini_set("soap.wsdl_cache_e
$server = new SoapServer("sxc.wsdl");
$server->addFunction("logi
$server->addFunction("uplo
$server->addFunction("dele
$server->handle();
?>
Drilling down ... ws_delete() please?
ASKER
It is in common_ws.php, a usual PHP file containing these functions. If I call those functions separately, they run well, returning the array needed. Just if called as SOAP webservice from the client above it fails. Here is the code for ws_common: (pointed out ... the other two functions in order not to make this post here too long:
<?
require_once ("../common.phtml");
require_once ("../../common.php");
include "iptc_lib.php";
function ws_login ($username, $password) {
...
}
function ws_delete ($username, $password, $files) {
$loginres = ws_login ($username, $password);
if ($loginres['status_num'] != 0)
return ($loginres);
briefcase_chkdir($username );
$dir=briefcase_getdir($use rname);
$files = explode (",",$files);
if (!is_array ($files))
return (array ('status_num' => '10', 'status_msg' => 'No files provided.'));
foreach ($files as $f) {
if (is_file ($dir ."/". $f)) {
$fname = $dir ."/" .$f;
if (!unlink ($fname))
$error = true;
}
else {
$error = true;
}
}
if ($error) {
return (array ('status_num' => '10', 'status_msg' => 'Could not delete all files.'));
}
else {
return (array ('status_num' => '0', 'status_msg' => 'Successfully removed all files.'));
}
}
function ws_upload ($username, $password, $title, $caption, $keywords, $filename) {
...
}
?>
<?
require_once ("../common.phtml");
require_once ("../../common.php");
include "iptc_lib.php";
function ws_login ($username, $password) {
...
}
function ws_delete ($username, $password, $files) {
$loginres = ws_login ($username, $password);
if ($loginres['status_num'] != 0)
return ($loginres);
briefcase_chkdir($username
$dir=briefcase_getdir($use
$files = explode (",",$files);
if (!is_array ($files))
return (array ('status_num' => '10', 'status_msg' => 'No files provided.'));
foreach ($files as $f) {
if (is_file ($dir ."/". $f)) {
$fname = $dir ."/" .$f;
if (!unlink ($fname))
$error = true;
}
else {
$error = true;
}
}
if ($error) {
return (array ('status_num' => '10', 'status_msg' => 'Could not delete all files.'));
}
else {
return (array ('status_num' => '0', 'status_msg' => 'Successfully removed all files.'));
}
}
function ws_upload ($username, $password, $title, $caption, $keywords, $filename) {
...
}
?>
Ah.
SoapClient->__call() - Calls a SOAP function (deprecated)
This method is deprecated. Use SoapClient->__soapCall() instead of it.
I can't tell you when it was deprecated.
SoapClient->__call() - Calls a SOAP function (deprecated)
This method is deprecated. Use SoapClient->__soapCall() instead of it.
I can't tell you when it was deprecated.
Can you show the wdsl file also.
ASKER
Hmm, but where was the call function in my code...?
Here is the WSDL:
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:sxc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:sxc">
<types>
<xsd:schema targetNamespace="urn:sxc">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
<xsd:complexType name="Status">
<xsd:all>
<xsd:element name="status_num" type="xsd:int" />
<xsd:element name="status_msg" type="xsd:string" />
</xsd:all>
</xsd:complexType>
</xsd:schema>
</types>
<message name="loginRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
</message>
<message name="loginResponse">
<part name="return" type="tns:Status" />
</message>
<message name="uploadRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
<part name="title" type="xsd:string" />
<part name="caption" type="xsd:string" />
<part name="keywords" type="xsd:string" />
<part name="base64_photo" type="xsd:string" />
</message>
<message name="uploadResponse">
<part name="return" type="tns:Status" />
</message>
<message name="deleteRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
<part name="files" type="xsd:string" />
</message>
<message name="deleteResponse">
<part name="return" type="tns:Status" />
</message>
<portType name="sxcPortType">
<operation name="login">
<documentation>check for login validity</documentation>
<input message="tns:loginRequest" />
<output message="tns:loginResponse " />
</operation>
<operation name="upload">
<documentation>upload test</documentation>
<input message="tns:uploadRequest " />
<output message="tns:uploadRespons e" />
</operation>
<operation name="delete">
<documentation>delete test</documentation>
<input message="tns:deleteRequest " />
<output message="tns:deleteRespons e" />
</operation>
</portType>
<binding name="sxcBinding" type="tns:sxcPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="login">
<soap:operation soapAction="urn:sxc#login" style="rpc" />
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
<operation name="upload">
<soap:operation soapAction="urn:sxc#upload " style="rpc" />
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
<operation name="delete">
<soap:operation soapAction="urn:sxc#delete " style="rpc" />
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="sxc">
<port name="sxcPort" binding="tns:sxcBinding">
<soap:address location="http://stockxpert.com/plugin/sxc_wsdl.php" />
</port>
</service>
</definitions>
Here is the WSDL:
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:sxc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:sxc">
<types>
<xsd:schema targetNamespace="urn:sxc">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
<xsd:complexType name="Status">
<xsd:all>
<xsd:element name="status_num" type="xsd:int" />
<xsd:element name="status_msg" type="xsd:string" />
</xsd:all>
</xsd:complexType>
</xsd:schema>
</types>
<message name="loginRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
</message>
<message name="loginResponse">
<part name="return" type="tns:Status" />
</message>
<message name="uploadRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
<part name="title" type="xsd:string" />
<part name="caption" type="xsd:string" />
<part name="keywords" type="xsd:string" />
<part name="base64_photo" type="xsd:string" />
</message>
<message name="uploadResponse">
<part name="return" type="tns:Status" />
</message>
<message name="deleteRequest">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
<part name="files" type="xsd:string" />
</message>
<message name="deleteResponse">
<part name="return" type="tns:Status" />
</message>
<portType name="sxcPortType">
<operation name="login">
<documentation>check for login validity</documentation>
<input message="tns:loginRequest"
<output message="tns:loginResponse
</operation>
<operation name="upload">
<documentation>upload test</documentation>
<input message="tns:uploadRequest
<output message="tns:uploadRespons
</operation>
<operation name="delete">
<documentation>delete test</documentation>
<input message="tns:deleteRequest
<output message="tns:deleteRespons
</operation>
</portType>
<binding name="sxcBinding" type="tns:sxcPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="login">
<soap:operation soapAction="urn:sxc#login"
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
<operation name="upload">
<soap:operation soapAction="urn:sxc#upload
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
<operation name="delete">
<soap:operation soapAction="urn:sxc#delete
<input>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:sxc" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="sxc">
<port name="sxcPort" binding="tns:sxcBinding">
<soap:address location="http://stockxpert.com/plugin/sxc_wsdl.php" />
</port>
</service>
</definitions>
wsdl file.
ASKER
Actually, sxc_wsdl.php is the server. (sorry for bit messed up naming)
http://stockxpert.com/plugin/sxc_wsdl.php
Outputs ...
<envelope SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><body><fault>< faultcode> SOAP-ENV:S erver</fau ltcode><fa ultstring> Bad Request. Can't find HTTP_RAW_POST_DATA</faults tring></fa ult></body ></envelop e>
What OS and webserver are the servers?
I vaguely remember this being an issue.
Can you check the
; Always populate the $HTTP_RAW_POST_DATA variable.
always_populate_raw_post_d ata = On
settings on both platforms.
Outputs ...
<envelope SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><body><fault><
What OS and webserver are the servers?
I vaguely remember this being an issue.
Can you check the
; Always populate the $HTTP_RAW_POST_DATA variable.
always_populate_raw_post_d
settings on both platforms.
ASKER
; Always populate the $HTTP_RAW_POST_DATA variable.
always_populate_raw_post_d ata = On
it's commented out on both servers - have a ; before always_populate_raw_post_d ata = On
The servers are Ubuntu Linux, Apache2, PHP 5.1.2
always_populate_raw_post_d
it's commented out on both servers - have a ; before always_populate_raw_post_d
The servers are Ubuntu Linux, Apache2, PHP 5.1.2
Remove the ;
I am pretty sure that there is a way, even uncommented, that this field is NOT populated.
Checking source ...
I am pretty sure that there is a way, even uncommented, that this field is NOT populated.
Checking source ...
From what I can tell, if you are sending the data via POST, then you use $_POST. If you are NOT using POST then you CAN use $HTTP_RAW_POST_DATA which seems wrong to me, but I may be reading that wrong.
Hmm.
soap.c is slightly different.
Can you check your php error log. There should be messages like ...
PHP-SOAP requires 'always_populate_raw_post_ data' to be on please check your php.ini file
This will also generate the SOAP fault of ...
soap_server_fault("Server" , "Bad Request. Can't find HTTP_RAW_POST_DATA" ...);
So. I think this is the issue.
Hmm.
soap.c is slightly different.
Can you check your php error log. There should be messages like ...
PHP-SOAP requires 'always_populate_raw_post_
This will also generate the SOAP fault of ...
soap_server_fault("Server"
So. I think this is the issue.
ASKER
Dear Sage,
sorry for the long delay - in the end there was a solution found to the problem. It wasn't exactly server setting related, but DNS related - due to some misconfiguration, the www.domain... from inside the server wasn't pointing back to the server, but to the load balancer in front of fronteds - this way, the server PHP couldn't be found from the WSDL file. After some configuring of DNS zone files the webservice worked perfectly.
I appreciate all your efforts to help with this, and would happily give you the points on this - however, I wouldn't accept one of your answers which wasn't exactly the solution. Could you advise me please how can I still add points?
sorry for the long delay - in the end there was a solution found to the problem. It wasn't exactly server setting related, but DNS related - due to some misconfiguration, the www.domain... from inside the server wasn't pointing back to the server, but to the load balancer in front of fronteds - this way, the server PHP couldn't be found from the WSDL file. After some configuring of DNS zone files the webservice worked perfectly.
I appreciate all your efforts to help with this, and would happily give you the points on this - however, I wouldn't accept one of your answers which wasn't exactly the solution. Could you advise me please how can I still add points?
If none of the comments constitute an answer, then you can ask for a refund in Community Support.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Can u explain this term "After some configuring of DNS zone files the webservice worked perfectly". What is the configuration u made to work the service fine?
It's going to be a trial and error issue to resolve.
Also, make sure you have the same version of all related dlls/extensions on the live server and of PHP itself.
Run this as info.php
<?php phpinfo(); ?>
on all the servers and check the differences.
Paying attention to SOAP settings.
Make sure the SOAP cache folder exists and you have permissions.
Output for Soap from php -i for me ...
soap
Soap Client => enabled
Soap Server => enabled
Directive => Local Value => Master Value
soap.wsdl_cache => 1 => 1
soap.wsdl_cache_dir => D:\Data\PHP\SOAP_Cache => D:\Data\PHP\SOAP_Cache
soap.wsdl_cache_enabled => 1 => 1
soap.wsdl_cache_limit => 5 => 5
soap.wsdl_cache_ttl => 86400 => 86400
Erm.
That's all I can think of for the time being.