I need to connect to a SOAP Server from php, I read a lot of documentation, examples and tutorials, but I still cannot make authentication to my server. I have done the work below:
$agencyNumber = 7818619810;
$fullTransmission = false;
//$context = array('header' => 'Content-type: application/soap+xml; charset=utf-8');
$params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => 0/*,$context*/);
$client = new SoapClient("http://link/to/server?wsdl");
$test = $client->__getFunctions();
var_dump($test );// returns the functions my supplier provides, as well __getTypes() gives a bunch of variable arrays ect..
$response = $client->__soapCall('GetTransmissionTicket',array($params) );//line 16 which is mentioned on error print
var_dump($response);
Even though I set $context, when I try to run, I get the error below:
Fatal error: Uncaught SoapFault exception: [HTTP] Cannot process the
message because the content type 'text/xml; charset=utf-8' was not the
expected type 'application/soap+xml; charset=utf-8'. in
C:\xampp\htdocs\xml\inc\connection_test.php:16 Stack trace: #0
[internal function]: SoapClient->__doRequest('http://interfac...', '..//my-provider...', 1, 0) #1
C:..path..test.php(16): SoapClient->__soapCall('GetTransmission...',
Array) #2 {main} thrown in C:..path..test.php on line 16
The remote method I'm trying to call is called GetTransmissionTicket which takes two parameters, (int)agencyNumber and fullTransmission(bool)..
I want to emphasize that there are a lot of threads on this topic, some of which are really close to my question(1, 2, 3 and so on ..), but I really couldn't solve the problem. Please give a hand..
Kind Regards..
Try $params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => false);
instead of $params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => 0);
OR
Use $client = new SoapClient("http://link/to/server?wsdl", array('soap_version' => SOAP_1_1));
because
application/soap+xml is the content-type passed when using SOAP 1.2, text/xml is used with SOAP 1.1,
Reference : how to change content-type of request?
A simple example with soap and php can be
$url="your WSDL url";
$method = "Method you are calling";
$error=0;
$client = new SoapClient($url);
try
{
$info = $client->__call($method, array($param));
}
catch (SoapFault $fault)
{
$error = 1;
errorReport($fault->faultcode,$fault->faultstring);
die;
/*echo '<script type="text/javascript">alert("Sorry,App Returne the following ERROR:'.$fault->faultcode."-".$fault->faultstring.' We will now take you back to our homepage."); window.location = "'.$_SERVER['PHP_SELF'].'";</script> '; */
}
if($error==1)
{
$xml=$fault->faultstring;
}else{
$xml = $info;
}
return $xml;
Try implementing it and let me know. if it works for you.
Shouldn't the last line be var_dump($response); instead of var_dump($client);
Anyways, you can also try using this to get the result :
$response = $client->GetTransmissionTicket(array($params) );
var_dump($response);
I resolved this problem by switching from SOAP 1.2 to SOAP 1.1:
$this->client = new SoapClient(
$url,
array(
"trace" => TRUE,
"exception" => 0,
"soap_version" => SOAP_1_1,
"cache_wsdl" => WSDL_CACHE_MEMORY,
"local_cert" => 'mycert.pem',
)
);
I will answer my own question so that it helps someone one day. I used nusoap and changed the encoding to utf-8. The code snippet is below:
require_once "nusoap.php";
$client = new nusoap_client("http://interface.--Serivce-Supplier-Link/Service.svc?wsdl", "wsdl");
$client->soap_defencoding = 'UTF-8';
$result = $client->call("GetTransmissionTicket", array( 'agencyNumber' => 13155, 'fullTransmission' => false));
var_dump($result);
Kind Regards
may be little late but could help others. so here it goes:
$params is already an array so you don't have to use array($params) in
$response = $client->__soapCall('GetTransmissionTicket',array($params) );
instead use simple $params while calling.check it like this
$response = $client->GetTransmissionTicket($params);
also use $client->__getTypes(); to verify params to be passed.
use catch to good effect to trace faultstringand faultactor.
at the end if still not getting solution check it with soapUI(a software).
Related
I have SOAP service with WSDL and php-client for it.
Php-client:
<?php
$client = new SoapClient('https://xx.xx.xx.xx/service/?wsdl');
$headers = array();
$headers[] = new SoapHeader('http://mfisoft.ru/auth','Login','admin');
$headers[] = new SoapHeader('http://mfisoft.ru/auth','Password','admin');
$client->__setSoapHeaders($headers);
$table_hi = $client->getTableByTitle('Blocked numbers');
$row_data = array(
array(
array(
'name' => 'prfx',
'value' => '55555555'
),
array(
'name' => 'blocking_time',
'value' => '20140306185014'
)
)
);
$rowset=$client->insertRowset($table_hi, $row_data);
?>
But I need to rewrite the python.
I tried to do using suds and pysimplesoap.
from suds.client import Client
url = 'http://localhost/service/?wsdl'
client = Client(url)
I don't understand how make similar program in particular these strings
$headers[] = new SoapHeader('http://mfisoft.ru/auth','Login','admin');
$headers[] = new SoapHeader('http://mfisoft.ru/auth','Password','admin');
$client->__setSoapHeaders($headers);
I have not found in suds doc.
I need your help.
Thanks in advance.
p.s.
Sorry for my bad English
P.S.S.
I need to rewrite the php client in the python client.
Forgive the formatting in advance.. the proper way to setup and connect using the suds client is as follows. In the case that you want the server part, I can't tell 100% from your question.. I might be able to help but it's not something I've ever done before in python.
client = suds.client.Client.(self,url=wsdl_url,
doctor=schema_doctor,
username=username)
try:
# This will throw an Exception if the wsdl_url is bad
# and will return False if the authentication fails
if not client.service.Connection_Authenticate(username,
password):
raise Exception("Failed to authenticate.")
I am all new to soap and i have only a little idea as to what im doing. Any attempts to fix the issue or find a description as to whats goin on have been fruitless. I can't seem to get rid of a constant nagging exception:
SoapFault exception: [500] Username required in path\index.php:38<br />
Stack trace:<br />
#0 path\index.php(38): SoapClient->__soapCall('createPlayer', Array)<br />
#1 {main}
The wsdl is here - http://www.laifacai.com/soap/gameprovider?wsdl
And this is in my php.
$soap_options = array('trace' => 1, 'exceptions' => 1 );
$client = new SoapClient("http://www.laifacai.com/soap/gameprovider?wsdl", array( 'login' => "user", 'password' => "pass"));
var_dump ($client->__getFunctions ());
if (!class_exists('SoapClient')){
die ("You haven't installed the PHP-Soap module.");
} else {
try {
$res = $client->__soapCall('createPlayer', array('username'=>'mstest1', 'password'=>'12345678')));
} catch (SOAPFault $f) {
echo "<pre>" . $f . "</pre>";
}
}
Basicaly, i have a few methods on the wsld that i would like to handle. I though that createPlayer would be the easiest one and i could get on from there based on what i've learned, but i can't get it right, i don't know whats wrong and i can't find it out. It doesent matter if i pass an empty array or a full one, allways the same "Username requiered".
Edit: Wsld link edited
It says "Username required", so try providing it. Currently you're only providing username (note the lower caps). SOAP is case sensitive.
Also, I think your
$res = $client->__soapCall('createPlayer',
array('username'=>'mstest1', 'password'=>'12345678')));
should be
$SoapCallParameters = array('username'=>'mstest1', 'password'=>'12345678');
$res = $client->__soapCall('createPlayer',
array('parameters'=>$SoapCallParameters));
According to your WSDL documentation, you should supply
array(
'agentid'
'username'
'password'
'currencycode'
'countrycode'
'nickname'
'fname'
'lname'
)
for createPlayer, so just username and password is not enough.
The variable $response in the below code is NULL even though it should be the value of the SOAP request. (a list of tides). When I call $client->__getLastResponse() I get the correct output from the SOAP service.
Anybody know what is wrong here? Thanks! :)
Here is my code :
$options = array(
"trace" => true,
"encoding" => "utf-8"
);
$client = new SoapClient("http://opendap.co-ops.nos.noaa.gov/axis/webservices/highlowtidepred/wsdl/HighLowTidePred.wsdl", $options);
$params = array(
"stationId" => 8454000,
"beginDate" => "20060921 00:00",
"endDate" => "20060922 23:59",
"datum" => "MLLW",
"unit" => 0,
"timeZone" => 0
);
try {
$result = $client->getHLPredAndMetadata($params);
echo $client->__getLastResponse();
}
catch (Exception $e) {
$error_xml = $client->__getLastRequest();
echo $error_xml;
echo "\n\n".$e->getMessage();
}
var_dump($result);
The reason that the $result (or the response to the SoapCall) is null is indeed because the WSDL is invalid.
I just ran into the same problem - the WSDL said the response should be PackageChangeBatchResponse yet the actual XML returns has PackageChangeResponse
Changing the WSDL to match the response / changing the response to match the WSDL resolves the issue
you should give an option parameter as below :
<?php
// below $option=array('trace',1);
// correct one is below
$option=array('trace'=>1);
$client=new SoapClient('some.wsdl',$option);
try{
$client->aMethodAtRemote();
}catch(SoapFault $fault){
// <xmp> tag displays xml output in html
echo 'Request : <br/><xmp>',
$client->__getLastRequest(),
'</xmp><br/><br/> Error Message : <br/>',
$fault->getMessage();
}
?>
"trace" parameter enables the output of request. Now, you should see the SOAP request.
(source: PHP.net
I've ran into trouble with SOAP, I've never had this issue before and can't find any information on line that helps me solve it.
The following code
$wsdl = "path/to/my/wsdl";
$client = new SoapClient($wsdl, array('trace' => true));
//$$textinput is passed in and is a very large string with rows in <item></item> tags
$soapInput = new SoapVar($textinput, XSD_ANYXML);
$res = $client->dataprofilingservice(array("contents" => $soapInput));
$response = $client->__getLastResponse();
var_dump($res);//outputs null
var_dump($response);//provides the proper response as I would expect.
I've tried passing params into the SoapClient constructor to define soap version but that didnt' help. I've also tried it with the trace param set to false and not present which as expected made $response null but $res was still null. I've tried the code on both a linux and windows install running Apache.
The function definition in the WSDL is (xxxx is for security reasons)
<portType name="xxxxServiceSoap">
<operation name="dataprofilingservice">
<input message="tns:dataprofilingserviceSoapIn"/>
<output message="tns:dataprofilingserviceSoapOut"/>
</operation>
</portType>
I have it working using the __getLastResponse() but its annoying me it will not work properly.
I've put together a small testing script, does anyone see any issues here. Do I need a structure for the return type?
//very simplifed dataset that would normally be
//read in from a CSV file of about 1mb
$soapInput = getSoapInput("asdf,qwer\r\nzzxvc,ewrwe\r\n23424,2113");
$wsdl = "path to wsdl";
try {
$client = new SoapClient($wsdl,array('trace' => true,'exceptions' => true));
} catch (SoapFault $fault) {
$error = 1;
var_dump($fault);
}
try {
$res = $client->dataprofilingservice(array("contents" => $soapInput));
$response = $client->__getLastResponse();
echo htmlentities($client->__getLastRequest());//proper request echoed
echo '<hr>';
var_dump($res);//null
echo "<hr>";
echo(htmlentities($response));//proper response echoed
} catch (SoapFault $fault) {
$error = 1;
var_dump($fault);
}
function getSoapInput($input){
$rows = array();
$userInputs = explode("\r\n", $input);
$userInputs = array_filter($userInputs);
//
$inputTemplate = " <contents>%s</contents>";
$rowTemplate = "<Item>%s</Item>";
//
$soapString = "";
foreach ($userInputs as $row) {
// sanitize
$row = htmlspecialchars(addslashes($row));
$xmlStr = sprintf($rowTemplate, $row);
$rows[] = $xmlStr;
}
$textinput = sprintf($inputTemplate, implode(PHP_EOL, $rows));
$soapInput = new SoapVar($textinput, XSD_ANYXML);
return $soapInput;
}
Ok after much digging it is related to relative namespaces, it appears that PHP doesn't handle them well within the WSDL or the SOAP Envelope. So since I don't have control of the SOAP Server I will continue to get the response via __getLastResponse();.
Hopefully this will save some people some time it was hard to find.
You are mixing things here. __getLastResponse() returns the bare XML string response from the server if you make use of the 'trace' => true option. That is for debugging only.
So regardless whether 'trace' => true or not, the method which you would like to call originally returns the same and that is totally normal. Setting tracing to on won't change the behaviour, it just offers an additional feature, the return value for __getLastResponse().
As the SoapClient does not throw any exception I'd say that your call is going okay and NULL is a valid return value.
You might want to provide the actual XML string and/or the WSDL defintion so that one could inspect if that's the case or not.
Ok my .net 4.0 client works fine. People using java all have no issues. But when it comes to php our php developer cant get anything to work.
Now keep in mind i did not create a Wcflibray project, i created a regular asp 4.0 website and then added a WCF Service so i do not have a app.config, i have a web.config.
We have went down to the bare essentials of creating two methods
string HelloWorld()
{
return "Hello!";
}
and
string HellowTomorrow(string sret)
{
return sret;
}
In debug mode i will see him enter my method but only with null. If i packet sniff with wireshark, he is not passing the paramater envelope.
I have googled endlessly but all examples are from a WCF service project, not a website that has added a WCF Service too it. (rememember, everyone else is having no problems, java, .net 2.0, etc)
Here is his php 5.3
error_reporting(E_ALL);
ini_set('display_errors','On');
$client = new SoapClient("http://99-mxl9461k9f:6062/DynamicWCFService.svc?wsdl", array('soap_version' => SOAP_1_1));
$client->soap_defencoding = 'UTF-8';
//$args = array('john');
$args = array('param1'=>'john');
$webService = $client->__soapCall('HelloTomorrow',$args);
//$webService = $client->HelloTomorrow($args);
var_dumpp($webService);
?>
While working with WCF service .net as Server and PHP-soap as client you need to follow guideline strictly. The documentation of PHP-soap is not enough to debug and not that clear either. PHP nusoap is little better on documentation but still not enough on example and not a great choice for the beginners. There are a few examples for nusoap but most of them don’t work.
I would suggest following debug checklist:
Check the binding in your web.config file. It has to be “basicHttpBinding” for PHP
PHP, $client->__soapCall() function sends all arguments as an array so if your web-service function require input parameters as an array then arguments has to be in an extra array. Example#3 is given below to clear.
If required then pass “array('soap_version' => SOAP_1_1)” or “array('soap_version' => SOAP_1_2)” to SoapClient() object to explicitly declare soap version.
Always try declaring “array( "trace" => 1 )” to SoapClient Object to read the Request & Response strings.
Use “__getLastResponse();” function to read Response String.
Use “__getLastRequest();” function to read Request String.
IMPORTANT:If you are getting NULL return for any value passed as
parameter then check your .cs(.net) file that look like this:
[ServiceContract]
public interface IDynamicWCFService
{
[OperationContract]
string HelloYesterday(string test);
}
The variable name passes here, have to match with when you call it in PHP. I am taking it as “test” for my examples below.
Example #1: using php-soap with single parameter for HelloYesterday function
<?php
$url="http://99-mxl9461k9f:6062/DynamicWCFService.svc?WSDL";
$client = new SoapClient($url, array( "trace" => 1 ));
$result = $client->HelloYesterday(array('test' => 'this is a string'));
var_dump($result);
$respXML = $client->__getLastResponse();
$requXML = $client->__getLastRequest();
echo "Request: <br>";
var_dump($requXML);
echo "Response: <br>";
var_dump($respXML);
?>
Example #2 : using nusoap with single parameter for HelloYesterday function
<?php
require_once('../lib/nusoap.php');
$proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : '';
$proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : '';
$proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : '';
$proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : '';
$url="http://99-mxl9461k9f:6062/DynamicWCFService.svc?WSDL";
$client = new nusoap_client($url, 'wsdl', $proxyhost, $proxyport, $proxyusername, $proxypassword); $client->soap_defencoding = 'UTF-8'; // this is only if you get error of soap encoding mismatch.
$err = $client->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// Doc/lit parameters get wrapped
$param = array('test' => ' This is a string for nusoap');
$result = $client->call('HelloYesterday', array('parameters' => $param), '', '', false, true);
// Check for a fault
if ($client->fault) {
echo '<h2>Fault</h2><pre>';
print_r($result);
echo '</pre>';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error
echo '<h2>Error</h2><pre>' . $err . '</pre>';
} else {
// Display the result
echo '<h2>Result</h2><pre>';
print_r($result);
echo '</pre>';
}
}
echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
?>
One more example… passing array as a parameter or pass mixed type parameter then check the following example:
Example #3: passing mixed type parameter including array parameter to Soap function.
Example of .net operation file
[ServiceContract]
public interface IDynamicWCFService
{
[OperationContract]
string[] HelloYesterday (string[] testA, string testB, int testC );
}
PHP code
<?php
$url="http://99-mxl9461k9f:6062/DynamicWCFService.svc?WSDL";
$client = new SoapClient($url, array( "trace" => 1 ));
$params = array(
"testA" => array(0=>"Value1",1=>"Value2",2=>"Value3"),
"testB" => “this is string abc”,
"testC" =>123
); // consider the first parameter is an array, and other parameters are string & int type.
$result = $client->GetData($params);
var_dump($result);
$respXML = $client->__getLastResponse();
$requXML = $client->__getLastRequest();
echo "Request: <br>";
var_dump($requXML);
echo "Response: <br>";
var_dump($respXML);
?>
Hope the above examples will help.
Since you're passing the wsdl location into the SoapClient constructor, you should be able to call $client->HelloTomorrow($args). There seem to be a few typos, though, can you verify that they are all correct in your actual code? In your web service code, you name the function HellowTomorrow but you're calling HelloTomorrow in your PHP code. Also, the parameter is named sret in your web service, but it's being passed as param1 in the $args associative array. Does it work calling HelloWorld() which doesn't expect any parameters?
Update:
See NuSOAP and content type
Try using the built-in PHP SoapClient instead of the NuSOAP version. PHP's SoapClient looks like it defaults to UTF-8, where NuSOAP seems to be hard-coded to ISO-8859-1