Passing Array via SOAP for SAP Webservice - php

I am trying to pass a 2D Array via SOAP for SAP Webservice.
But I am unable to pass the same.
I am able to pass a value, also I am able to accept a table output from SAP.
Please guide.
I tried to typecast array as an object.
My Code:
<?php
include("include/config.php");
$sql = "SELECT tid,OrderNumber FROM transhistory ORDER by timestamp ASC limit 2";
$result= mysqli_query($db,$sql);
$i=0;
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)) {
//Array based on output table
$pmt[$i][0] = ""; //Mandt
$pmt[$i][1] = $row["tid"]; //Refnum
$pmt[$i][2] = $row["OrderNumber"]; //Orderno
$i++;
}
/*Two methods I tried */
$object = (object) $pmt;
$object = json_decode(json_encode($pmt), FALSE);
#Define Authentication
$SOAP_AUTH = array( 'login' => 'abc',
'password' => 'abc');
#Specify WSDL
$WSDL = "working URL here";
#Create Client Object, download and parse WSDL
$client = new SoapClient($WSDL,$SOAP_AUTH);
#Setup input parameters (SAP Likes to Capitalise the parameter names)
$params = array(
'Zpmt' => $object
);
#Call Operation (Function). Catch and display any errors
try {
$result = $client->ZphpOT($params);
} catch (SoapFault $exception) {
echo 'Error!Server Connectivity issue. Please try again later.';
die();
}
?>

I don't know if the answer may be useful for somebody but usually you send parameters like this
$result = $client->ZphpOT("VARIABLE_NAME"=>$params);

Related

How to get big record data from external API in laravel 5.7

I want to get 28,000 records data from external API.
For this, I use nusoap_client. However, when I test it I don't get any data and I don't get any error.
This is my function:
public function get_all(){
$url = "http://xxx.xx.x.xx:xxx/services/Pending?wsdl";
$client = new \nusoap_client($url, 'wsdl');
$pDate = isset($_GET["Date"]) ? $_GET["Date"] : '26/2/2017 01:01:01';
$operation = 'getPendingData';
$param1 = array(
'Date' => $Date,
);
$result = $client->call($operation, $param1);
print_r($result);
exit();
}
In the API I must get data starting from 26/02/2017 01:01:01. When I test it I don't get any data. When I changed date to 27/02/2017 01:01:01 I got 759 records data.
How to fix this?

How to remove backslash from json response of php soap web service?

My wsdl file :-
<?php
/**
#Description: Book Information Server Side Web Service:
This Sctript creates a web service using NuSOAP php library.
fetchBookData function accepts ISBN and sends back book information.
#Author: http://programmerblog.net/
#Website: http://programmerblog.net/
*/
require_once('dbconn.php');
require_once('lib/nusoap.php');
$server = new nusoap_server();
/* Fetch 1 book data */
function presentStatusPull($rnbcode){
global $dbconn;
$sql = "SELECT * FROM rnb_gpl_data where did = :rnbcode";
// prepare sql and bind parameters
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(":rnbcode", $rnbcode);
// insert a row
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_ASSOC);
return json_encode($data);
$dbconn = null;
}
$server->configureWSDL('index', 'urn:index');
$server->register('presentStatusPull',
array('rnbcode' => 'xsd:string'),
array('data' => 'xsd:string'),
'urn:index',
'urn:index#presentStatusPull'
);
$server->service(file_get_contents("php://input"));
?>
Then my php file for call the wsdl server:-
<?php
require_once('lib/nusoap.php');
$result = array();
$wsdl = "http://meter.digireach.com/RnBCode/index.php?wsdl";
$rnbcode = $_GET['rnbcode'];
//create client object
$client = new nusoap_client($wsdl, true);
$result = $client->call('presentStatusPull', array($rnbcode));
// $result = json_decode($result);
// echo json_encode($result);
echo json_encode($result, JSON_NUMERIC_CHECK);
?>
and response of url :- http://meter.digireach.com/RnBCode/presentstatus.php?rnbcode=DR00098EM
and output is like this:-
"{\"srno\":\"1\",\"tr_date\":\"2017-08-22 11:53:33\",\"did\":\"DR00098EM\",\"p1\":\"455\",\"p2\":\"0\",\"p3\":\"0\",\"p4\":\"48\",\"p5\":\"0\",\"p6\":\"0\",\"p7\":\"60\",\"p8\":\"40\",\"p9\":\"0\",\"p10\":\"0\",\"p11\":\"5\",\"p12\":\"0\",\"p13\":\"0\",\"p14\":\"1103\",\"p15\":\"36170\",\"p16\":\"511046\",\"p17\":\"0\",\"p18\":\"1\",\"p19\":\"1\",\"p20\":\"1\",\"tno\":\"Ideal\",\"ser_date\":\"2017-08-22 11:54:12\"}"
so,I want to remove backslash() from this json response.
You didn't set valid JSON header this is why your API response is string not JSON.
Solution 1:
You should set valid Content-Type header before JSON output. Like following:
header('Content-Type: application/json');
echo json_encode($result, JSON_NUMERIC_CHECK);
or, Solution 2:
Decode your output twice json_decode(json_decode($json))

PHP ibase query

i want to use PHP for internet service in my IOS 7 application.
I've tried to generate an code for receiving objects from a Firebird database.
My Code bellow:
<?php
$host = 'xxx';
$username = 'xxx';
$password = 'xxx';
$conn = ibase_connect($host, $username, $password) or
die ("Verbindung fehlgeschlagen");
$arr = array();
$data = array();
$stmt = "select * from xxx";
$sth = ibase_query($conn, $stmt);
while ($row = ibase_fetch_object ($sth)) {
$data['ID'] = $row->ID;
$data['VON'] = $row->VON;
$data['AN'] = $row->AN;
$data['BETREFF'] = $row->BETREFF;
$data['DATUM'] = $row->DATUM;
$data['KOMMISSIONSNR'] = $row->KOMMISSIONSNR;
$data['NACHRICHT'] = $row->NACHRICHT;
$data['GELESEN'] = $row->GELESEN;
$data['GEANTWORTET'] = $row->GEANTWORTET;
$data['STATUS'] = $row->STATUS;
$data['AUFTRAG'] = $row->AUFTRAG;
$arr[] = array($data);
}
echo json_encode($arr);
?>
By calling the code in Safari-browser no values or arrays be returned.
If giving an Key like 1
(echo json_encode($arr[1]);) an array on the browser will be shown.
How can i show the whole array with all keys? I should add that i want to use the results from my ibase-query as NSDictionary in the application.
And which framework is the best for encoding the PHP-Array to IOS? I've tried to use JSONDictionaryExtensions, but don't know if it's the right for this Code.
i hope you can help me.
Sorry for my bad english.
I'm not sure why you are putting the $data array into another array. You can skip that step.
When you echo json_encode($data) you encode the array as JSON, so that is what your iOS application gets and what it needs to decode. Decoding JSON into an NSArray or NSDictionary has been asked many times here on StackOverflow, like this question.

php soapclient returns null but getPreviousResults has proper results

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.

PHP+SoapClient exceptions and headers? (UPS Rating)

I'm trying to use PHP and SoapClient to utilize the UPS Ratings web service. I found a nice tool called WSDLInterpreter to create a starting point library for creating the service requests, but regardless what I try I keep getting the same (non-descriptive) error:
EXCEPTION=SoapFault::__set_state(array(
'message' => 'An exception has been raised as a result of client data.',
'string' => '',
'code' => 0,
Um ok, what the hell does this mean?
Unlike some of the other web service tools I have implemented, the UPS Soap wants a security block put into the header. I tried doing raw associative array data but I wasn't sure 100% if I was injecting the header part correctly.
Using the WSDLInterpreter, it pulls out a RateService class with a ProcessRate method that excepts it's own (instance) datastructure for the RateRequest and UPSSecurity portions, but all of the above generates that same error.
Here's a sample of the code that I'm using that calls classes defined by the interpreter:
require_once "Shipping/UPS/RateService.php"; // WSDLInterpreter class library
class Query
{
// constants removed for stackoverflow that define (proprietary) security items
private $_upss;
private $_shpr;
// use Interpreter code's RateRequest class to send with ProcessRate
public function soapRateRequest(RateRequest $req, UPSSecurity $upss = null)
{
$res = false;
if (!isset($upss)) {
$upss = $this->__getUPSS();
}
echo "SECURITY:\n" . var_export($upss, 1) . "\n";
$upsrs = new RateService(self::UPS_WSDL);
try {
$res = $upsrs->ProcessRate($req, $upss);
} catch (SoapFault $exception) {
echo 'EXCEPTION=' . var_export($exception, 1) . "\n";
}
return $res;
}
// create a soap data structure to send to web service from shipment
public function getRequestSoap(Shipment $shpmnt)
{
$qs = new RateRequest();
// pickup information
$qs->PickupType->Code = '01';
$qs->Shipment->Shipper = $this->__getAcctInfo();
// Ship To address
$qs->Shipment->ShipTo->Address->AddressLine = $this->__getAddressArray($shpmnt->destAddress->address1, $shpmnt->destAddress->address2);
$qs->Shipment->ShipTo->Address->City = $shpmnt->destAddress->city;
$qs->Shipment->ShipTo->Address->StateProvinceCode = $shpmnt->destAddress->state;
$qs->Shipment->ShipTo->Address->PostalCode = $shpmnt->destAddress->zip;
$qs->Shipment->ShipTo->Address->CountryCode = $shpmnt->destAddress->country;
$qs->Shipment->ShipTo->Name = $shpmnt->destAddress->name;
// Ship From address
$qs->Shipment->ShipFrom->Address->AddressLine = $this->__getAddressArray($shpmnt->origAddress->address1, $shpmnt->origAddress->address2);
$qs->Shipment->ShipFrom->Address->City = $shpmnt->origAddress->city;
$qs->Shipment->ShipFrom->Address->StateProvinceCode = $shpmnt->origAddress->state;
$qs->Shipment->ShipFrom->Address->PostalCode = $shpmnt->origAddress->zip;
$qs->Shipment->ShipFrom->Address->CountryCode = $shpmnt->origAddress->country;
$qs->Shipment->ShipFrom->Name = $shpmnt->origAddress->name;
// Service type
// TODO cycle through available services
$qs->Shipment->Service->Code = "03";
$qs->Shipment->Service->Description = "UPS Ground";
// Package information
$pkg = new PackageType();
$pkg->PackagingType->Code = "02";
$pkg->PackagingType->Description = "Package/customer supplied";
// dimensions
$pkg->Dimensions->UnitOfMeasurement->Code = $shpmnt->dimensions->dimensionsUnit;
$pkg->Dimensions->Length = $shpmnt->dimensions->length;
$pkg->Dimensions->Width = $shpmnt->dimensions->width;
$pkg->Dimensions->Height = $shpmnt->dimensions->height;
$pkg->PackageServiceOptions->DeclaredValue->CurrencyCode = "USD";
$pkg->PackageServiceOptions->DeclaredValue->MonetaryValue = $shpmnt->dimensions->value;
$pkg->PackageServiceOptions->DeclaredValue->CurrencyCode = "USD";
$pkg->PackageWeight->UnitOfMeasurement = $this->__getWeightUnit($shpmnt->dimensions->weightUnit);
$pkg->PackageWeight->Weight = $shpmnt->dimensions->weight;
$qs->Shipment->Package = $pkg;
$qs->CustomerClassification->Code = 123456;
$qs->CustomerClassification->Description = "test_rate_request";
return $qs;
}
// fill out and return a UPSSecurity data structure
private function __getUPSS()
{
if (!isset($this->_upss)) {
$unmt = new UsernameToken();
$unmt->Username = self::UPSS_USERNAME;
$unmt->Password = self::UPSS_PASSWORD;
$sat = new ServiceAccessToken();
$sat->AccessLicenseNumber = self::UPSS_ACCESS_LICENSE_NUMBER;
$upss = new UPSSecurity();
$upss->UsernameToken = $unmt;
$upss->ServiceAccessToken = $sat;
$this->_upss = $upss;
}
return $this->_upss;
}
// get our shipper/account info (some items blanked for stackoverflow)
private function __getAcctInfo()
{
if (!isset($this->_shpr)) {
$shpr = new ShipperType();
$shpr->Address->AddressLine = array(
"CONTACT",
"STREET ADDRESS"
);
$shpr->Address->City = "CITY";
$shpr->Address->StateProvinceCode = "MI";
$shpr->Address->PostalCode = "ZIPCODE";
$shpr->Address->CountryCode = "US";
$shpr = new ShipperType();
$shpr->Name = "COMPANY NAME";
$shpr->ShipperNumber = self::UPS_ACCOUNT_NUMBER;
$shpr->Address = $addr;
$this->_shpr = $shpr;
}
return $this->_shpr;
}
private function __getAddressArray($adr1, $adr2 = null)
{
if (isset($adr2) && $adr2 !== '') {
return array($adr1, $adr2);
} else {
return array($adr1);
}
}
}
It doesn't even seem to be getting to the point of sending anything over the Soap so I am assuming it is dying as a result of something not matching the WSDL info. (keep in mind, I've tried sending just a properly seeded array of key/value details to a manually created SoapClient using the same WSDL file with the same error resulting)
It would just be nice to get an error to let me know what about the 'client data' is a problem. This PHP soap implementation isn't impressing me!
I know this answer is probably way too late, but I'll provide some feedback anyway. In order to make a custom SOAP Header you'll have to override the SoapHeader class.
/*
* Auth Class to extend SOAP Header for WSSE Security
* Usage:
* $header = new upsAuthHeader($user, $password);
* $client = new SoapClient('{...}', array("trace" => 1, "exception" => 0));
* $client->__setSoapHeaders(array($header));
*/
class upsAuthHeader extends SoapHeader
{
...
function __construct($user, $password)
{
// Using SoapVar to set the attributes has proven nearly impossible; no WSDL.
// It might be accomplished with a combined SoapVar and stdClass() approach.
// Security Header - as a combined XSD_ANYXML SoapVar
// This method is much easier to define all of the custom SoapVars with attributes.
$security = '<ns2:Security xmlns:ns2="'.$this->wsse.'">'. // soapenv:mustUnderstand="1"
'<ns2:UsernameToken ns3:Id="UsernameToken-49" xmlns:ns3="'.$this->wsu.'">'.
'<ns2:Username>'.$user.'</ns2:Username>'.
'<ns2:Password Type="'.$this->password_type.'">'.htmlspecialchars($password).'</ns2:Password>'.
'</ns2:UsernameToken>'.
'</ns2:Security>';
$security_sv = new SoapVar($security, XSD_ANYXML);
parent::__construct($this->wsse, 'Security', $security_sv, false);
}
}
Then call the upsAuthHeader() before the soap call.
$client = new SoapClient($this->your_ups_wsdl,
array('trace' => true,
'exceptions' => true,
'soap_version' => SOAP_1_1
)
);
// Auth Header - Security Header
$header = new upsAuthHeader($user, $password);
// Set Header
$client->__setSoapHeaders(array($header));

Categories