passing an array to web-service php nusoap - php

i have a problem with passing an array to a web-service function that i created with php and nusoap.
the problem is that i guess i'm doing something wrong.. i suspect that the problem is in the function or in my client side. when i send an array it doesn't go into the function i registered with the web-service. i only get response of empty array when i call the web-service.
i hope someone can help me here.
thanks.
EDIT: I managed to fix it. i forgot to build a struct for the request.
server side:
<?php
//include nusoap
require_once('c:\\wamp\\www\\nusoap.php');
//create server instance
$server = new soap_server();
//configure wsdl
$server->wsdl->schemaTargetNamespaces = 'urn:GetArr';
$server->configureWSDL('GetArr','urn:GetArr');
$server->wsdl->addComplexType(
'Product',
'complexType',
'struct',
'all',
'',
array(
'name' => array('name' => 'name', 'type' => 'xsd:string'),
'code' => array('name' => 'code', 'type' => 'xsd:string'),
'price' => array ('name' => 'price', 'type' => 'xsd:int'),
'quantity' => array ('name' => 'quantity', 'type' => 'xsd:int'),
'total_price' => array('name' => 'total_price', 'type' => 'xsd:int')
));
//this is what i was missing
$server->wsdl->addComplexType(
'ArrayReq',
'complexType',
'struct',
'all',
'',
array(
'name' => array('name' => 'name', 'type' => 'xsd:string'),
'code' => array('name' => 'code', 'type' => 'xsd:string'),
'price' => array ('name' => 'price', 'type' => 'xsd:int'),
'quantity' => array ('name' => 'quantity', 'type' => 'xsd:int')
));
//until here.
$server->wsdl->addComplexType(
'ProductArray',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:Product[]')),
'tns:Product');
//function that get and return values
function GetTotalPrice ($proArray) {
$temparray = array();
$temparray[] = array('name' => $proArray['name'], 'code' => $proArray['code'], 'price' => $proArray['price'], 'quantity'
=> $proArray['quantity'], 'total_price' => $proArray['quantity'] * $proArray['price']);
return $temparray;
};
//register the method
$server->register('GetTotalPrice',
array('proArray' => 'tns:ArrayReq'),// and this line also.
array('return' => 'tns:ProductArray'),
'urn:GetArr',
'urn:GetArr#GetTotalPrice',
'rpc',
'encoded',
'Get the product total price'
);
//run the service
$post = file_get_contents('php://input');
$server->service($post);
?>
client side
<?php
//include nusoap
require_once('c:\\wamp\\www\\nusoap.php');
ini_set ('soap.wsdl_cache_enabled', 0);
$arr['name'] = "GoPro";
$arr['code'] = "245";
$arr['price'] =70;
$arr['quantity'] = 4;
$sClient = new nusoap_client('http://localhost/nusoap/comserv.php?wsdl','wsdl','','','','');
$response = $sClient->call('GetTotalPrice',array($arr),'','', false,true);
$error = $sClient->getError();
if ($error) {
echo "<h2>Constructor error</h2><pre>" . $error . "</pre>";
}
if ($sClient->fault) {
echo "<h2>Fault</h2><pre>";
echo ($response);
echo "</pre>";
}
else {
$error = $sClient->getError();
if ($error) {
echo "<h2>Error</h2><pre>" . $error . "</pre>";
}
if ($response != "" || NULL){
echo "<h2>Respond</h2><pre>";
print_r ($response);
echo "</pre>";
}
}
?>
this is the output(respond)
Respond
Array
(
[0] => Array
(
[name] =>
[code] =>
[price] =>
[quantity] =>
[total_price] => 0
)
)
EDIT:
this is the fixed output.
Respond
Array
(
[0] => Array
(
[name] => GoPro
[code] => 245
[price] => 70
[quantity] => 4
[total_price] => 280
)
)

ok so i fixed it. i added comments so anyone can see what i added in order to make it work..
i needed to make a struct for the request so my function will know the array type. also fixed it in the function registration.

Related

PHP - SoapClient() returns Fatal error: Uncaught SoapFault exception: [xml_structure] String could not be parsed as XML

I have got this code to make request to the webservice, however it poops Fatal error: Uncaught SoapFault exception: [xml_structure] String could not be parsed as XML on call.
Any ideas how may i solve it?
All of the variables prefixed with $ are set well, the problem seems to be in the way I try to call the method.
Full code:
$client = new SoapClient("url/to/wsdl");
$contract = array(
'product' => array(
'prefix' => 'MOP',
),
'participants' => array(
'customers' => array(
'main_borrower' => array(
'personal_data' => array(
'pesel' => $pesel,
'firstname' => $firstname,
'lastname' => $lastname,
'sex' => $xmlsex,
),
'contact_data' => array(
'addresses' => array(
'address' => array(
'type' => 'registered',
'street_name' => $city,
'block_number' => '1',
'flat_number' => '1',
'postal_code' => $postcode,
'city' => $city,
),
),
'phones_mobile' => array(
'phone_mobile' => array(
'type' => 'personal',
'number' => $phone,
),
),
),
'incomes' => array(
'income' => array(
'type' => 'employment',
'main_income' => 'true',
'fixed_term_contract' => 'false',
'paychecks' => array(
'paycheck' => array(
'amount_net' => array(
'amount' => $price,
'currency' => 'PLN',
),
'type' => 'base',
),
),
),
),
),
),
),
);
$parameters = array(
'user_login' => 'xxx',
'user_password' => 'xxx',
'contract' => $contract,
);
$response = $client->newApplication($parameters);
Also - previously i used objects (=> [ 'xxx' => 'xxx' ],) instead of arrays but still wouldn't do the trick.
Actually the mistake i made was not making $contract and XML object.
To do so i used the following example:
//function defination to convert array to xml
function array_to_xml($array, &$xml_user_info) {
foreach($array as $key => $value) {
if(is_array($value)) {
if(!is_numeric($key)){
$subnode = $xml_user_info->addChild("$key");
array_to_xml($value, $subnode);
}else{
$subnode = $xml_user_info->addChild("item$key");
array_to_xml($value, $subnode);
}
}else {
$xml_user_info->addChild("$key",htmlspecialchars("$value"));
}
}
}
//creating object of SimpleXMLElement
$xml_user_info = new SimpleXMLElement("<?xml version=\"1.0\"?><user_info></user_info>");
//function call to convert array to xml
array_to_xml($users_array,$xml_user_info);
//saving generated xml file
$xml_file = $xml_user_info->asXML('users.xml');
//success and error message based on xml creation
if($xml_file){
echo 'XML file have been generated successfully.';
}else{
echo 'XML file generation error.';
}
Original version and tribute to author: https://www.codexworld.com/convert-array-to-xml-in-php/

insert variable in array php foreach

i have a function with a dynamic array.
function doIt($accountid,$targeting){
$post_url= "https://url".$accountid."/";
$fields = array(
'name' => "test",
'status'=> "PAUSED",
'targeting' => array(
$targeting
),
);
$curlreturn=curl($post_url,$fields);
};
And i want to build the array "$fields" dynamically within a foreach loop. Like that:
$accountid="57865";
$targeting=array(
"'device_platforms' => array('desktop'),'interests' => array(array('id' => '435345','name' => 'test')),",
"'device_platforms' => array('mobile'), 'interests' => array(array('id' => '345345','name' => 'test2')),",
);
foreach ($targeting as $i => $value) {
doit($accountid,$value);
}
The Problem is, that the array within the function will not be correctly filled. If i output the array in the function i get something like:
....[0] => array('device_platforms' => array('desktop'),'custom_audiences'=> ['id' => '356346']), )
The beginning [0] should be the problem. Any ideas what im doing wrong?
Hope this will help you out. The problem was the way you are defining $targeting array. You can't have multiple keys with same name
Change 1:
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
Change 2:
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting //removed array
);
Try this code snippet here this will just print postfields
<?php
ini_set('display_errors', 1);
function doIt($accountid, $targeting)
{
$post_url = "https://url" . $accountid . "/";
$fields = array(
'name' => "test",
'status' => "PAUSED",
'targeting' => $targeting
);
print_r($fields);
}
$accountid = "57865";
$targeting = array(
array(
'device_platforms' => array('desktop'),
'interests' => array(
array('id' => '435345',
'name' => 'test')),
),
array(
'device_platforms' => array('mobile'),
'interests' => array(
array('id' => '345345',
'name' => 'test2'))
)
);
foreach ($targeting as $i => $value)
{
doit($accountid, $value);
}

NuSOAP returns empty array

I have the problem, that the NuSOAP server returns an empty array. I read and tried a lot of topics/things already but the result is always the same. I guess its only a minor thing you guys can solve within a minute.
I want to put an array of strings containing client information into another array that holds all servers:
Array
(
[Client1] => Array ([HostName] => 'TestHostName', [IP] => '1.1.1.1'),
[Client2] => Array ([HostName] => 'TestHostName', [IP] => '2.2.2.2'),
[Client3] => Array ([HostName] => 'TestHostName', [IP] => '3.3.3.3')
)
The arrays will get filled from mysql data, but for testing purposes I created a static array with data. Here is what I have got so far:
<?php
require_once ('lib/nusoap.php');
require('mysql.php');
$ServerName = 'server';
$ServiceName = 'CentralConfigService';
$ServiceURL = 'http://' . $ServerName . '/' . $ServiceName;
$Server = new soap_server();
$Server -> configureWSDL($ServiceName, $ServerName . '/' . $ServiceName);
function GetClientInfo($ClientName)
{
$Clients = array();
$ClientInfo = array(
'HostName' => 'testiname',
'IP' => 'testip',
'Type' => 'testtype',
'Config' => 'testconfig',
'Routines' => 'testroutines',
'Files' => 'testfiles',
'Access' => 'testaccess');
$Clients[$ClientName] = $ClientInfo;
return $Clients;
}
$Server -> wsdl -> addComplexType(
'ClientInfo',
'complexType',
'struct',
'sequence',
'',
array(
'HostName' => array('name' => 'HostName', 'type' => 'xsd:string'),
'IP' => array('name' => 'IP', 'type' => 'xsd:string'),
'Type' => array('name' => 'Type', 'type' => 'xsd:string'),
'Config' => array('name' => 'Config', 'type' => 'xsd:string'),
'Routines' => array('name' => 'Routines', 'type' => 'xsd:string'),
'Files' => array('name' => 'Files', 'type' => 'xsd:string'),
'Access' => array('name' => 'Access', 'type' => 'xsd:string')
)
);
$Server -> wsdl -> addComplexType(
'Clients',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:ClientInfo')
),
'tns:Clients'
);
$Server -> register(
'GetClientInfo',
array('HostName' => 'xsd:string'),
array('return' => 'tns:Clients'),
$ServiceURL,
$ServiceURL . '#GetClientInfo',
'rpc',
'encoded',
'Get config by type');
if ( !isset( $HTTP_RAW_POST_DATA ) ) $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );
#$Server -> service($HTTP_RAW_POST_DATA);
?>
when I call the function "GetClientInfo", I always get an empty array:
Array
(
[0] => Array
(
[0] => Array
(
)
[1] => Array
(
)
[2] => Array
(
)
[3] => Array
(
)
[4] => Array
(
)
[5] => Array
(
)
[6] => Array
(
)
)
)
The client calls the function:
<?php
require_once('lib/nusoap.php');
$wsdl = "http://server/server.php?wsdl";
$client = new nusoap_client($wsdl, 'wsdl');
$result = $client -> call('GetClientInfo', array('ClientName'=>'Client1'));
print_r($result);
?>
Sorry for the long post. I hope it contains all necessary information.
Thanks a lot in advance!
Cheers,
Daniel
I found my mistake. The complexType that includes the struct has to look like that:
$Server -> wsdl -> addComplexType(
'Clients',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:ClientInfo')
),
'tns:ClientInfo'
So 'tns:ClientInfo' instead of 'tns:Clients' in the last line.
Here is a fully functioning example:
server.php
<?php
// Includes
require_once ('lib/nusoap.php');
require('mysql.php');
require('cc_functions.php');
// General SOAP configuration
$ServerName = 'server';
$ServiceName = 'CentralConfigService';
$ServiceURL = 'http://' . $ServerName . '/' . $ServiceName;
$Server = new soap_server();
$Server -> configureWSDL($ServiceName, $ServerName . '/' . $ServiceName);
function GetClientInfo($ClientName)
{
$Clients = array();
$Clients1 = array(
'HostName' => 'testiname',
'IP' => 'testip',
'Type' => 'testtype',
'Config' => 'testconfig',
'Routines' => 'testroutines',
'Files' => 'testfiles',
'Access' => 'testaccess');
$Clients2 = array(
'HostName' => 'testiname2',
'IP' => 'testip2',
'Type' => 'testtype2',
'Config' => 'testconfig2',
'Routines' => 'testroutines2',
'Files' => 'testfiles2',
'Access' => 'testaccess2');
array_push($Clients, $Clients1);
array_push($Clients, $Clients2);
return $Clients;
}
$Server -> wsdl -> addComplexType(
'ClientInfo',
'complexType',
'struct',
'all',
'',
array(
'ID' => array('name' => 'ID', 'type' => 'xsd:integer'),
'HostName' => array('name' => 'HostName', 'type' => 'xsd:string'),
'IP' => array('name' => 'IP', 'type' => 'xsd:string'),
'Type' => array('name' => 'Type', 'type' => 'xsd:string'),
'Config' => array('name' => 'Config', 'type' => 'xsd:string'),
'Routines' => array('name' => 'Routines', 'type' => 'xsd:string'),
'Files' => array('name' => 'Files', 'type' => 'xsd:string'),
'Access' => array('name' => 'Access', 'type' => 'xsd:string')
)
);
$Server -> wsdl -> addComplexType(
'Clients',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:ClientInfo[]')
),
'tns:ClientInfo'
);
$Server -> register(
'GetClientInfo',
array('ClientName' => 'xsd:string'),
array('return' => 'tns:Clients'),
$ServiceURL,
$ServiceURL . '#GetClientInfo',
'',
'rpc',
'Get config by type');
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = file_get_contents('php://input');
#$Server -> service($HTTP_RAW_POST_DATA);
?>
client.php
<?php
require_once('lib/nusoap.php');
$wsdl = "http://server/server.php?wsdl";
$client = new nusoap_client($wsdl, 'wsdl');
$result = $client -> call('GetClientInfo', array('ClientName'=>''));
print_r($result);
?>

Multidimensional associative array as response in NuSOAP

I have some problems with response in SOAP. In general I can not undertand how to get response as multidimensional associative array for my SOAP-client.
I used NuSOAP v 1.123 library.
So I have that code in SOAP-server:
$server->wsdl->addComplexType(
'ReturnDataInside',
'complexType',
'struct',
'all',
'',
array(
'message' => array('name' => 'message', 'type' => 'xsd:string', 'nillable' => 'true'),
'value' => array('name' => 'value', 'type' => 'xsd:string', 'nillable' => 'true'),
)
);
$server->wsdl->addComplexType(
'ReturnDataOutside',
'complexType',
'array',
'all',
'',
array(),
array(),
'tns:ReturnDataInside'
);
$server->register('test',
array('param_1' => 'xsd:int', 'param_2' => 'xsd:string'),
array('return' => 'tns:ReturnDataOutside')
);
function test($param_1, $param_2)
{
$data = array(
'test' => array(
'message' => 'string',
'value' => 'string',
),
);
return $data;
}
My response looks like that:
Array
(
[0] => Array
(
[message] => string
[value] => string
)
)
So what to change to get 'test' as a key in my response m.array ?
First of all body of my function was incorrect.
$data[] = array(
'message' => 'string',
'value' => 'string',
);
And the answer on my quastion is:
soap does not send keys for multidimensional arrays.

PHP Betfair Free Access API, how to build APIRequestHeader & call any method?

I am trying to write a simple PHP client to get some data from Betfair through the Free Access API http://bdp.betfair.com/?option=com_content&task=view&id=33&Itemid=62
I can login & get a session token, this way
$wsdl = 'https://api.betfair.com/global/v3/BFGlobalService.wsdl';
$soapClient = new SoapClient($wsdl);
try {
$ap_param = array(
'request' =>
array(
'username' => 'my_username',
'password' => 'my_password',
'productId' => '82',
'ipAddress' => '',
'locationId' => '',
'vendorSoftwareId' => '',
),
);
$response = $soapClient->__call("login", array($ap_param));
...
$response is an object containing the sessionToken param
But after several tries I am afraid I am sending the APIRequestHeader param (http://bdp.betfair.com/docs/) malformed, cause the response to any call (getAllEventTypes, for instance) is always returning the same: NO_SESSION
One try...
$ap_param = array(
'request' =>
array(
'header' => array(
'session_token' => $response->Result->header->sessionToken,
'clientStamp' => 0,
),
),
);
Another try...
$ap_param = array(
'request' =>
array(
'session_token' => $response->Result->header->sessionToken,
'clientStamp' => 0,
),
);
And lot of other tries... but
$response = $soapClient->__call("getAllEventTypes", array($ap_param));
$response is always the same
stdClass Object
(
[Result] => stdClass Object
(
[header] => stdClass Object
(
[errorCode] => NO_SESSION
[minorErrorCode] =>
[sessionToken] =>
[timestamp] => 2013-11-09T08:41:01.015Z
)
[eventTypeItems] =>
[minorErrorCode] =>
[errorCode] => API_ERROR
)
)
Someone here has faced the same problem?
Stupid typo error there...
session_token should be sessionToken
$ap_param = array(
'request' =>
array(
'header' => array(
'sessionToken' => $response->Result->header->sessionToken,
'clientStamp' => 0,
),
),
);

Categories