Zend HTTP Client Invalid URI supplied? - php

I'm having trouble using Zend HTTP on a URL:
$bestBuyClient = new Zend_Http_Client('https://api.bestbuy.com/v1/products(search=pizza&salePrice>10&salePrice<15)?apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription');
$response = $bestBuyClient->request();
$json="";
if($response->isSuccessful()){
$jsonTxt=$response->getBody();
$json = #json_decode($jsonTxt,true);
}
$jsonProducts=$json;
return $jsonProducts;
For some reason, this gives me an error:
Invalid URI supplied
Whats wrong this this specific url?
Edit: In PostMan or browser request sends proper data.

Can you change:
$bestBuyClient = new Zend_Http_Client('https://api.bestbuy.com/v1/products(search=pizza&salePrice>10&salePrice<15)?apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription');
$response = $bestBuyClient->request();
To
$shoppableClient = new Zend_Http_Client(sprintf('https://api.bestbuy.com/v1/products'."%s?%s", urlencode('(search=pizza&salePrice>10&salePrice<15)'), 'apiKey=MyKeyHere&page=1&numItems=10&format=json&show=sku&name&productId&type&regularPrice&salePrice&upc&modelNumber&image&largeFrontImage&mediumImage&thumbnailImage&largeImage&shortDescription&longDescription'));
Please let me know if works :).

Related

PHP Soap calling Error

I am trying to connect to webservice using SOAP / wsdl, but I constantly get the error. I am new in soap-api in php. I have a document of api detail, it shows:
public WSGetCalendarFareResponse GetCalendarFare(WSGetCalendarFareRequest calanderFareRequest)
I made my code accordingly but still found error/exception. Please review my php code in following:
$wsdl = "http://api.abc.com/xyz/service.asmx?wsdl"; // This is a test Web Service URL
$h = array();
$opta["GetCalendarFare"]["request"]= array(
"Origin"=>"DEL",
"Destination"=>"IXR",
"DepartureDate"=>"2015-05-01T00:00:00",
"ReturnDate"=>"2015-05-01T00:00:00",
"Type"=>"OneWay",
"CabinClass"=>"All",
"PreferredCarrier"=>"",
"AdultCount"=>1,
"ChildCount"=>1,
"InfantCount"=>"0",
"SeniorCount"=>"0",
"PromotionalPlanType"=>"Normal",
"IsDirectFlight"=>false
);
$client_header = new SoapHeader('http://192.168.0.0/TEST/BookingAPI','AuthenticationData',$hparams,false);
$cliente = new SoapClient($wsdl, array('trace' => 0));
$cliente->__setSoapHeaders(array($client_header));
try{
$h= (array)$cliente->__call('GetCalendarFare',$opta);
}catch(Exception $e)
{
echo '<pre>';
var_dump($e);
}
When I execute my code, it returns following error:
"System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at BookingAPI.WSCalendarFareInput(WSGetCalendarFareRequest calanderFareRequest) in c:\inetpub\wwwroot\api.tektravel.com\TboApi_V7\App_Code\Service.cs:line 4544
at BookingAPI.GetCalendarFare(WSGetCalendarFareRequest calanderFareRequest) in c:\inetpub\wwwroot\api.tektravel.com\TboApi_V7\App_Code\Service.cs:line 4360
Can anyone please suggest that where problem exists? It hit & try many times but couldn't get the error point.
Can you debug the execution of your POST on the server side? It is heavy guessing from my side, but I assume that you do not set a mandatory value in the request, which the server needs to deserialize your object. Hence the NullReferenceException.
Problem has resolved.
The Request array should be like this:
$opta["GetCalendarFare"]["calanderFareRequest"]= array(
"Origin"=>"DEL",
"Destination"=>"IXR",
"DepartureDate"=>"2015-05-01T00:00:00",
"ReturnDate"=>"2015-05-01T00:00:00",
"Type"=>"OneWay",
"CabinClass"=>"Economy",
"PreferredCarrier"=>"",
"AdultCount"=>1,
"ChildCount"=>1,
"InfantCount"=>"0",
"SeniorCount"=>"0",
"PromotionalPlanType"=>"Normal",
"IsDirectFlight"=>false
);

Guzzle Http Client ambiguous response

Here's my code in a different file
use Symfony\Component\DomCrawler\Crawler;
$guzzle = new GuzzleHttp\Client(['base_url' => 'http://pricematch.pk/mobile/samsung-galaxy-s6-80514-price-in-Pakistan']);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
echo $crawler->filter('.product-shop-wrapper .price')->text()."\r\n";
The url in this one is hardcoded and this one successfully echos the filtered text. When the same url/any url in the each loop in below code comes from a variable
$guzzle = new GuzzleHttp\Client(['base_url' => 'pricematch.pk/mobile-phone-prices-in-pakistan']);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
$crawler->filter('.product-name')->each(function ($node,$counter) {
echo $counter." ".$node->text()."\r\n";
$url=$node->filter('a')->extract(array('href'))[0]."\r\n";
echo $url."\r\n";
$url='http://pricematch.pk'.$url;
echo $url;
$guzzle = new GuzzleHttp\Client(['base_url' => $url]);
$response = $guzzle->get();
$crawler = new Crawler((string)$response->getBody());
the crawler throws an exception saying the current node list is empty. The href returns a relative url which I append with root url in the above code. I have printed the resultant url a lot many times. The filter throws exception even when the url is same as in code#1.
What am I doing wrong? Update 2: I just found out that data in code2 crawler is coming from
pricematch.pk/mobile-phone-prices-in-pakistan
Where it should be coming from
$url
What's goin on here?
Stupid me. While extracting URL in above code, I concatenated the newline character which got maybe encoded the URL to come out as __ at the end of the URL which basically changed the URL and hence the changed response.

Zend 2 REST Client Post Method sending header parameters also

In the Zend Framework 2, using REST Client using the POST method, the post URL has the query string,
As normal in postman when the request is post, the post content i have set
{"authToken":"11111111111111"} and post, status success.
when i get this value using GET method i have get the response, {"authToken":"11111111111111"}
which is correct.
when i run this through, php zend 2 using below method,
protected function genericSendRequest($url, $rawJsonData = NULL, $param = array()){
$response = '';
if(!empty($param)) {
$url .= '?' . http_build_query($param);
}
$client = $this->getHttpClient();
$client->setUri($url);
$client->setMethod('POST');
if($rawJsonData != null) {
$client->setRawBody(json_encode($rawJsonData));
}
$response = $client->send();
if ($response->isSuccess()) {
return $response->getContent();
}
return NULL;
}
Request Input,
$rawJsonData = array("authToken"=>"11111111111111");
$param = array("id"=>"9e770c9f71b4ef1b4ae85c58b0be4280253f9a2e");
Response i got,
id=9e770c9f71b4ef1b4ae85c58b0be4280253f9a2e&%7B%22authToken%22%3A%2211111111111111%22%7D=
This look like a URL query string,
i need the the response {"authToken":"11111111111111"}
ie. I need to get what i have post but i am getting post + query string,
query string is additionally posting to the request, that so its getting in the response,
how should avoid posting this querying string.
what the change needed in my code.?
Any help much appreciated.
Thanks in advance.
You question isn't very clear, but assuming you want to POST JSON data rather than form encoded data, you want:
if ($rawJsonData != null) {
$client->setRawBody(json_encode($rawJsonData));
}
Also, you could rewrite the query string part of your function to just:
if (!empty($param)) {
$uri .= '?' . http_build_query($param);
}

SOAP error. Not getting correct structure returned

I have a website that contains a form that makes various SOAP requests at certain points. One of these requests gets a list of induction times returned and displays them to the user in order for them to pick one.
I am getting results returned fine from the SOAP service but unfortunately it seems to be not showing information correctly and even not displaying returned object keys at all.
I have liased with one of the devs at the SOAP end and he says the service is fine and spitting out the cirrect information. He has provided a screentshot:
Here is my code to pull call the method I need for this information:
public function getInductionTimes($options) {
$client = $this->createSoapRequest();
$inductionTimes = $client->FITinductionlist($options);
//die(print_r($inductionTimes));
return $inductionTimes;
}
private function createSoapRequest() {
$url = 'https://fitspace.m-cloudapps.com:444/FITSPACE/MHservice.asmx?WSDL';
$options["connection_timeout"] = 25;
$options["location"] = $url;
$options['trace'] = 1;
$options['style'] = SOAP_RPC;
$options['use'] = SOAP_ENCODED;
$client = new SoapClient($url, $options);
//die(print_R($client->__getFunctions()));
return $client;
}
As you can see I print_r the code right after I have received it to check what I am getting returned and it is this:
As you can see this IDdtstring field is getting completely ignored.
Does anyone have any ideas as to why this may be happening? Is it something to do with encoding? I can't seem to get anywhere on this issue!
Thanks
I was able to retrieve the fields correctly, including IDdtstring, using your basic code. Perhaps you are not sending the parameters correctly?
function getInductionTimes($options) {
$client = createSoapRequest();
$inductionTimes = $client->FITinductionlist($options);
die(print_r($inductionTimes));
return $inductionTimes;
}
function createSoapRequest() {
$url = 'https://fitspace.m-cloudapps.com:444/FITSPACE/MHservice.asmx?WSDL';
$options["connection_timeout"] = 25;
$options["location"] = $url;
$options['trace'] = 1;
$options['style'] = SOAP_RPC;
$options['use'] = SOAP_ENCODED;
$client = new SoapClient($url, $options);
//die(print_R($client->__getFunctions()));
return $client;
}
getInductionTimes(array("IDDate" => "2013-06-28T13:00:00+01:00", "GYMNAME" => "Bournemouth"));
I managed to solve this issue by adding the line of code into my SOAP options array which I then presume was an issue with my WSDL being cached in PHP:
$options['cache_wsdl'] = WSDL_CACHE_NONE;

Need help building a webservice called Nusoap

Been having major issues trying to solve this issue, I'll be happy to give a +500 bounty to someone who can help me get this work.
Basically, I'm trying to call this web service using Nusoap:
https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
This is what I've got so far:
class Eway
{
var $username = 'test#eway.com.au';
var $pw = 'test123';
var $customerId = '87654321';
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
}
When I run this code and do $eway->getCustomer() I get the following error:
Array
(
[faultcode] => soap:Client
[faultstring] => eWayCustomerID, Username and Password needs to be specified in the soap header.
)
What am I doing wrong?
If you could fix my class and give me working code which is able to do the QueryCustomer method using the test customer id and return its info, I'll be glad to give you +500 rep and my eternal gratitude. Obviously it'll be 48 hours before I can start the bounty, but I promise that I will do it.
I could be missing the point, but you never actually assign the returned object to $client:
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
You could also set $client as a class variable if desired or by sending the parameter as a reference.
Looking at the data, I do not know if this matters, but you are using var for your class variable declarations and then using private for the function. If you are using php5 I would stay away from the var:
private $username = 'test#eway.com.au';
private $pw = 'test123';
private $customerId = '87654321';
Use the private or public or protected (whichever your class requires) instead to keep consistency. I doubt this will solve your problem, just something to be conscious about.
Possible Solution
Ok, doing some digging of my own, figured this out, you need to encase the actual header you add in a SOAP:Header deal. I tested the below and it was working for me, so give it a try:
private function setHeaders($client)
{
$headers = <<<EOT
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP:Header>
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
</SOAP:Header>
EOT;
$client->setHeaders($headers);
return $client;
}
It did not return any errors. So yea, it seems that is the likely culprit. (Note I also implemented the $client = $this->setHeaders($client); I mentioned above as well.
And my Final Answer is:
Alright did a bit of digging and found something that works. Not saying it is right, but yea it works.
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 123456789012)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, $namespace='https://www.eway.com.au/gateway/managedpayment', $soapAction='https://www.eway.com.au/gateway/managedpayment/QueryCustomer');
print_r($result);
//echo "\n{$client->request}\n"; // This echos out the response you are sending for debugging.
}
It seems the namespace and soapAction were the key ingredients. I found these using the link you originally posted: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
Basically, I just looked at that response, and then did some searching to figure out the soapAction, and then just messed with it until the request being sent matched the page you posted. It returns a failed login, but yea. That generally means something is working, and is probably due to the test data. But that gives you a baseline to go off of.
And the $client->request is a handy debugging tool for the future.
Update 5:
nusoap actually wraps the request with SOAP-ENV, like:
<SOAP-ENV:Header><eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWayCustomerID>87654321</eWayCustomerID>
<Username>test#eway.com.au</Username>
<Password>test123</Password>
</eWAYHeader></SOAP-ENV:Header>
While in the docs for EWay soap:Header must be used. I couldn't find a mention of the latter in nusoap headers.
Update 4:
This link has a good tip:
Got it. It was a case issue but not
there, and their PDF is incorrect.
For anyone that gets this in the
future, the PDF says:
<eWAYHeader
xmlns="http://www.eway.com.au/gateway/managedPayment">
It should be:
<eWAYHeader
xmlns="https://www.eway.com.au/gateway/managedpayment">
So this right here:
$client->setHeaders($headers);
The SoapClient class doesn't have that method. Instead, you can create a new SoapHeader.
private function setHeaders($client)
{
$headers = new stdClass;
$headers->eWAYCustomerID = $this->customerId;
$headers->Username = $this->username;
$headers->Password = $this->pw;
$ewayHeader = new SoapHeader(
"http://www.eway.com.au/gateway/managedPayment",
"eWAYHeader",
$headers
);
$client->__setSoapHeaders(array($ewayHeader));
return $client;
}
Edit: Alright, digging deeper:
private function prepHeaders()
{
return array(
'eWAYHeader' => array(
'eWAYCustomerID' => $this->customerId,
'Username' => $this->username,
'Password' => $this->pw
)
);
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, null, null, $this->prepHeaders());
print_r($result);
}
What happens if you do that?
I know this is not a full solution to the issue, but although this question is quite old, my findings may help lead to a concrete resolution.
I've been experiencing a similar error in relation to your mention of the HTTP "SOAPAction" header. (I am, however, dealing with a different eWay API than you. I'm dealing with the "Rapid API", which last week was renamed to from "Merchant Hosted Payments", which was part of the reason why my script wasn't working).
To return to the point, I found that if you don't specify the HTTP "SOAPAction" header, eWay returns a SoapFault with the following error message.
"System.Web.Services.Protocols.SoapException: Unable to handle request without a valid action parameter. Please supply a valid soap action."
If you add the HTTP "SOAPAction" header, you get an error no matter what you set it to.
"System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: XXX"
I'm also told by a member of eWay's support staff that they have an issues with an internal redirect, which they are now looking into resolving.
<ME> (2012-05-25 02:50:18)
I had an idea of what it could be. What is the "SOAPAction" HTTP header supposed to be set to?
<ME> (2012-05-25 02:52:05)
I couldn't find it in the documentation.
<EWAY_SUPPORT_STAFF> (2012-05-25 02:53:38)
The only thing that is required typically is the endpoint which is https://au.ewaypayments.com/hotpotato/soap.asmx and the <CreateAccessCode xmlns="https://au.ewaypayments.com/hotpotato/">
<EWAY_SUPPORT_STAFF> (2012-05-25 02:54:10)
In my tests it is working but what is happening is that requests are being redirected to the old URL which does not accept the CreateAccessCode method
<ME> (2012-05-25 02:56:58)
You did say that.
<ME> (2012-05-25 02:57:13)
So is this bug happening in the production environment?
<EWAY_SUPPORT_STAFF> (2012-05-25 02:57:57)
Yes it appears so. I have escalated this to Development and attached our last chat transcript and my own test results. They are looking at it now.

Categories