PHP Soap non-WSDL call: how do you pass parameters? - php

I'm trying to make a non-WSDL call in PHP (5.2.5) like this. I'm sure I'm missing something simple. This call has one parameter, a string, called "timezone":
$URL = 'http://www.nanonull.com/TimeService/TimeService.asmx';
$client = new SoapClient(null, array(
'location' => $URL,
'uri' => "http://www.Nanonull.com/TimeService/",
'trace' => 1,
));
// First attempt:
// FAILS: SoapFault: Object reference not set to an instance of an object
$return = $client->__soapCall("getTimeZoneTime",
array(new SoapParam('ZULU', 'timezone')),
array('soapaction' => 'http://www.Nanonull.com/TimeService/getTimeZoneTime')
);
// Second attempt:
// FAILS: Generated soap Request uses "param0" instead of "timezone"
$return = $client->__soapCall("getTimeZoneTime",
array('timezone'=>'ZULU' ),
array('soapaction' => 'http://www.Nanonull.com/TimeService/getTimeZoneTime')
);
Thanks for any suggestions
-Dave

Thanks. Here's the complete example which now works:
$URL = 'http://www.nanonull.com/TimeService/TimeService.asmx';
$client = new SoapClient(null, array(
'location' => $URL,
'uri' => "http://www.Nanonull.com/TimeService/",
'trace' => 1,
));
$return = $client->__soapCall("getTimeZoneTime",
array(new SoapParam('ZULU', 'ns1:timezone')),
array('soapaction' => 'http://www.Nanonull.com/TimeService/getTimeZoneTime')
);

#Dave C's solution didn't work for me. Looking around I came up with another solution:
$URL = 'http://www.nanonull.com/TimeService/TimeService.asmx';
$client = new SoapClient(null, array(
'location' => $URL,
'uri' => "http://www.Nanonull.com/TimeService/",
'trace' => 1,
));
$return = $client->__soapCall("getTimeZoneTime",
array(new SoapParam(new SoapVar('ZULU', XSD_DATETIME), 'timezone')),
array('soapaction' => 'http://www.Nanonull.com/TimeService/getTimeZoneTime')
);
Hope this can help somebody.

The problem lies somewhere in the lack of namespace information in the parameter. I used the first case of your example since it was closest to what I came up with.
If you change the line:
array(new SoapParam('ZULU', 'timezone')),
to:
array(new SoapParam('ZULU', 'ns1:timezone')),
it should give you the result you expected.

You could try to add another array() call around your params like this:
$params = array('timezone'=>'ZULU' );
$return = $client->__soapCall("getTimeZoneTime",
array($params),
array('soapaction' => 'http://www.Nanonull.com/TimeService/getTimeZoneTime')
);
I can't test this, but you could.

Related

How do I configure default query parameters with Guzzle 6?

Migrating from 5 to 6, and I've run into a snag and can't find the relevant docs.
Guzzle docs here, http://guzzle.readthedocs.io/en/latest/quickstart.html#creating-a-client, site that we can add "any number of default request options".
I want to send "foo=bar" with every request. E.g.:
$client = new Client([
'base_uri' => 'http://google.com',
]);
$client->get('this/that.json', [
'query' => [ 'a' => 'b' ],
]);
This will generate GET on http://google.com/this/that.json?a=b
How do I modify the client construction so that it yields:
http://google.com/this/that.json?foo=bar&a=b
Thanks for your help!
Alright, so far, this works here:
$extraParams = [
'a' => $config['a'],
'b' => $config['b'],
];
$handler = HandlerStack::create();
$handler->push(Middleware::mapRequest(function (RequestInterface $request) use ($extraParams) {
$uri = $request->getUri();
$uri .= ( $uri ? '&' : '' );
$uri .= http_build_query( $extraParams );
return new Request(
$request->getMethod(),
$uri,
$request->getHeaders(),
$request->getBody(),
$request->getProtocolVersion()
);
}));
$this->client = new Client([
'base_uri' => $url,
'handler' => $handler,
'exceptions' => false,
]);
If anyone knows how to make it less sinister-looking, I would say thank you!
I found a nice solution here.
Basically, anything defined in the first array of arguments, become part of the config for the client.
this means you can do this when initialising:
$client = new Client([
'base_uri' => 'http://google.com',
// can be called anything but defaults works well
'defaults' => [
'query' => [
'foo' => 'bar',
]
]
]);
Then, when using the client:
$options = [
'query' => [
'nonDefault' => 'baz',
]
];
// merge non default options with default ones
$options = array_merge_recursive($options, $client->getConfig('defaults'));
$guzzleResponse = $client->get('this/that.json', $options);
It's woth noting that the array_merge_recursive function appends to nested arrays rather than overwrites. If you plan on changing a default value, you'll need a different utility function. It works nicely when the default values are immutable though.
A "less sinister-looking" example based on the answer by #Saeven and the comment from #VladimirPak.
$query_defaults = [
'a' => $config['a'],
'b' => $config['b'],
];
$handler = \GuzzleHttp\HandlerStack::create();
$handler->push(\GuzzleHttp\Middleware::mapRequest(function (\Psr\Http\Message\RequestInterface $request) use ($query_defaults) {
$query = \GuzzleHttp\Psr7\Query::parse($request->getUri()->getQuery());
$query = array_merge($query_defaults, $query);
return $request->withUri($request->getUri()->withQuery(\GuzzleHttp\Psr7\Query::build($query)));
}));
$this->client = new \GuzzleHttp\Client([
'base_uri' => $url,
'handler' => $handler,
'exceptions' => false,
]);
I'm not sure how less sinister-looking it is though. lol
the solution proposed in github looks pretty ugly. This does not look much better, but at least is more readable and also works. I'd like feedback if anyone knows why should not be used:
$query = $uri . '/person/id?personid=' . $personid . '&name=' . $name;
return $result = $this->client->get(
$query
)
->getBody()->getContents();

Object reference not set to an instance of an object

It tells me that Object reference not set to an instance of an object, when trying to call this SOAP API.
I am doing this way
$client = new SoapClient("http://gateway.XXXXXXX/gateway/api/creditcards/creditcardAPI.asmx?wsdl");
$params = array("clsCreditCardAPIBE" => (Object) array(
"Username" => 'blabla',
"Password" => "Barrel of Oil",
"ProviderPIN" => 500,
"AccountID" => 1234
.......
));
$response = $client->__soapCall("Initiate_Deposit", $params);
What am i doing wrong?
You have to generate the client first, and then start using it
$client = new SoapClient("http://yourdomain.com?wsdl");

GuzzleHttp\Client::request() must be of the type array, boolean given

Ok i used "guzzlehttp/guzzle": "~6.0" for laravel.
it works on the server, but it does not work on my XAMPP, i don't know what is the problem. This is the error code.
Argument 3 passed to GuzzleHttp\Client::request() must be of the type array, boolean given
This is the code:
$param_data = array(
'api_user' => Config::get('sendgrid.api_user'),
'api_key' => Config::get('sendgrid.api_key'),
'list' => Config::get('sendgrid.list'),
'email' => 'xxxxxxx#yahoo.com',
);
$client = new Client();
$client->setDefaultOption('verify', false);
$res = $client->request(
'GET',
'https://api.sendgrid.com/api/newsletter/lists/email/get.json',
[
'query' => $param_data
]
);
$arr_res = json_decode($res->getBody());
print_r( $arr_res );
Same error I resolved it like this in my code
$param_data = array(
'api_user' => Config::get('sendgrid.api_user'),
'api_key' => Config::get('sendgrid.api_key'),
'list' => Config::get('sendgrid.list'),
'email' => 'xxxxxxx#yahoo.com',
);
$client = new Client();
$client->setDefaultOption('verify', false);
$res = $client->request(
array(
'GET',
'https://api.sendgrid.com/api/newsletter/lists/email/get.json?query='.$param_data,
));
$arr_res = json_decode($res->getBody());
print_r( $arr_res );
Also if your using Laravel request and Guzzle Request in same page so you need to use it like.
use Illuminate\Http\Request;
use GuzzleHttp\Psr7\Request as GuzzleRequest;
Try this hope this will work for you :)

How to use php soap instead of nusoap

I've got an specification web app that uses nusoap extension. But on our server runs php 5.5.
I tried to rewrite this example below but its beyond my capabilities...
Here is the script i want to rewrite to use soap in php without nusoap:
<?php
require_once('lib/nusoap.php');
$Client = new nusoap_client( 'https://letsgo-test.org', array( 'encoding'=>'UTF-8' ) );
$Client -> soap_defencoding = 'utf-8';
$Client -> decode_utf8 = FALSE;
$CMsg = array( 'user_name' => 'letsgo', 'user_password' => '123' );
$bClient = $Client->call( 'Login', $CMsg );
$szSession = $bClient[ 'session' ];
$bCPrep = array(
'rname1' => 'Lets',
'rname2' => 'Go',
'rcountry' => 'ORG',
'rzipcode' => '00-770',
);
$CMsg = array( 'session' => $szSession, 'consign_prep_data' => $bCPrep );
$bClient = $Client->call( 'adePreparingBox_Insert', $CMsg );
print_r( $bClient );
$CMsg = array( 'session' => $szSession );
$bClient = $Client->call( 'Logout', $CMsg );
?>
I will be gratefull for any help!!!.
Yep! I found solution!
Its not that hard as i thought,
Some of declarations looks diffrent:
$szSession = $bClient[ 'session' ];
changed to
$szSession = $bClient->session;
instead of "call" you need to use "__soapCall"
So thats what you need to do to free from nusoap.php
I guess there are more things to change but its enought for me.
Best Regards!

SOAP to XML conversion in PHP

I need to generate the following XML with SOAP:
...
<InternationalShippingServiceOption>
<ShippingService>StandardInternational</ShippingService>
<ShippingServiceCost currencyID="USD">39.99</ShippingServiceCost>
<ShippingServicePriority>1</ShippingServicePriority>
<ShipToLocation>CA</ShipToLocation>
</InternationalShippingServiceOption>
...
So I have the following SOAP array in PHP to do this:
$params = array(
'InternationalShippingServiceOption' => array(
'ShippingService'=>'StandardInternational',
'ShippingServiceCost'=>39.99,
'ShippingServicePriority'=>1,
'ShipToLocation'=>'CA',
)
)
$client = new eBaySOAP($session); //eBaySOAP extends SoapClient
$results = $client->AddItem($params);
Everything works great, except I am not generating the currencyID="USD" attribute in the ShippingServiceCost tag in the XML. How do I do this?
You don't need to use SoapVar. This works (for me at least):
$params = array(
'InternationalShippingServiceOption' => array(
'ShippingService'=>'StandardInternational',
'ShippingServiceCost' => array('_' => 39.99, 'currencyID' => 'USD')
'ShippingServicePriority'=>1,
'ShipToLocation'=>'CA',
)
)
I'm using this technique with the PayPal SOAP API.
Why, I am glad you asked. I just solved this today.
$shippingsvccostwithid = new SoapVar(array('currencyID' => $whatever),SOAP_ENC_OBJECT, 'ShippingServiceCost', 'https://your.namespace.here.com/');
$params = array("InternationalShippingServiceOption" => array(
"ShippingService" => "StandardInternational",
"ShippingServiceCost" => $shippingsvccostwithid,
"ShippingServicePriority" => 1,
"ShipToLocation" => "CA"
);
And then continue as normal.
Please let me know if you need any more help.

Categories