I am using ZF2 and curl for connecting with one of my clients API.
For example I am getting the response as
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Content-Type: application/json; charset=ISO-8859-1 Date: Thu, 04 Dec 2014 06:12:13 GMT Server: Google Frontend Cache-Control: private Alternate-Protocol: 80:quic,p=0.02,80:quic,p=0.02 Connection: close { "time": "06:12:13 AM", "milliseconds_since_epoch": 1417673533861, "date": "12-04-2014" }
I need the JSON array only.
My code is:
$data = "";
$adapter = new Curl();
$client = new Client();
$client->setAdapter($adapter);
$client->setUri('http://date.jsontest.com');
$client->setMethod('POST');
$adapter->setCurlOption(CURLOPT_POST, 1);
$adapter->setCurlOption(CURLOPT_POSTFIELDS, $data);
$adapter->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
$adapter->setCurlOption(CURLOPT_HTTPHEADER, array(
'Content-type: application/json',
'Authorization: Bearer $token'
));
$response = $client->send();
return new ViewModel(array(
'response' => $response,
));
The send() method of the Zend HTTP Client returns a new Response instance after successfully complete the request. You're directly passing that response instance to your view, not the content (body) inside the response.
Try this:
// Your current code..
$response = $client->send();
$viewModel = new ViewModel();
if($response->getStatusCode() === 200) {
$obj = json_decode($response->getBody(), true);
if($obj === null) {
// Json cannot be decoded.. handle it..
}
$viewModel->setVariable('response', $obj);
} else {
// Status code is not 200, handle it..
}
// And return the model
return $viewModel;
Not perfect but it should work..
Related
I'm trying to send a post request that header is json and the response also is json. What i have tried so far. This always return a status code 400. what i'm doing wrong?Thanks
private function requestPOST($url,$data)
{
App::uses('HttpSocket', 'Network/Http');
App::uses('Json', 'Utility');
$this->layout = 'default';
$this->autoRender = true;
$HttpSocket = new HttpSocket();
$jsonData = json_encode($data);
$request = array('header' => array('Content-Type' => 'application/json'));
debug($url);
$response = $HttpSocket->post($url, $jsonData, $request);
debug($response->code);
//$this->render('index');
$jsonString = json_decode($response['body'], true);
debug($jsonString);
return $jsonString;
}
I have solved myself. I was doing twice json_encode of the $data.
I don't know what I'm doing wrong but I've already lost a couple days struggling with this.
Here is my cURL request from the command line:
curl -i -H "Accept: text/html" http://laravel.project/api/v1/users/4
This returns:
HTTP/1.1 200 OK
Server: nginx/1.6.2
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
Date: Sun, 29 Mar 2015 10:33:36 GMT
Set-Cookie: laravel_session=eyJpdiI6ImNPTkZIYVJZSVRKaHBOZTR3SWh0dHc9PSIsInZhbHVlIjoiblpZYVJlN2dBY1ljejNIYUQycXpsNXRWd1I5a3JSRG8wSWdDOWlHVTMrYUcrdDBNVmVuZUNkOGtJb2M4bXFpTFF3cUdoTFZOVXBWXC82Q1luSGd5bjJBPT0iLCJtYWMiOiI0ZTEwOWQxMmVhMzY2NjI1Yzc1MTBmZmRmYjUyOGQwNDlhYzRjOTNiM2FiOWIyN2E1YjA0OTM4YTUxZmNmMzMzIn0%3D; expires=Sun, 29-Mar-2015 12:33:36 GMT; Max-Age=7200; path=/; httponly
{
"data":{
"id":4,
"name":"Helena",
"email":"hh#gmail.com",
"created_at":"2015-03-26 21:13:16",
"updated_at":"2015-03-26 21:13:16"
}
}
So everything looks fine: the Content-type is correctly set and response is in JSON.
But now watch what happens if I consume the API with curl in PHP:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $final_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
$result = curl_exec($ch);
return json_decode($result);
I get this response:
{#165
+"data": {#167
+"id": 4
+"name": "Helena"
+"email": "hh#gmail.com"
+"created_at": "2015-03-26 21:13:16"
+"updated_at": "2015-03-26 21:13:16"
}
}
And, if I return the $result without json_decode, I get this:
"{
"data":{
"id":4,
"name":"Helena",
"email":"hh#gmail.com",
"created_at":"2015-03-26 21:13:16",
"updated_at":"2015-03-26 21:13:16"
}
}"
The correct response but inside quotes. I've read in PHP docs that curl_opt_returntranfer returns the result as a string but I can't be the only person on the planet that just wants to get the JSON.
This is my ApiController class:
class ApiController extends Controller {
// Base controller for API Controllers
protected $statusCode = 200;
protected function respond($data)
{
return Response::json([
'data' => $data,
]);
}
protected function respondNotFound($message = 'No data found')
{
return Response::json([
'error' => [
'message' => $message,
'status_code' => $this->getStatusCode(),
]
]);
}
}
This is my UserController:
class UserController extends ApiController {
public function show($user)
{
if ($user == null)
return $this->setStatusCode(404)->respondNotFound('User not found');
return $this->respond($user);
}
}
And if I return the $result without json_decode i get this: The correct response but inside quotes
nope, what makes you think that? i guess the problem is how you are printing it, you are most likely printing it with var_export($result) or var_dump($result) or echo json_encode($result); which is adding the quotes. if you just want the json, just echo it with echo $result;, no extra processing, just echo the string as-is, it's already json.
I think this will solve your problem:
curl -i -H "Accept: text/html" http://laravel.project/api/v1/users/4 | tr -d '"'
$response = (string)$result;
$resp_arr = explode("<!DOCTYPE",$response);
$obj = json_decode(trim($japi_arr[0]));
if(isset($obj[0]))
{
$rsp_id = $obj[0]->id;
$rsp_name = $obj[0]->name;
Http post return data with invalid characters
$url = 'https://sandbox.itunes.apple.com/verifyReceipt';
$params = array('receipt-data' => 'receipt data');
$params = json_encode($params);
my code is
$client = new Client();
$client->setUri($url);
$client->setMethod('POST');
$client->setRawBody($params);
$client->setHeaders(array(
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
));
$client->setAdapter(new Curl());
$response = $client->send();
$res = $response->getContent();
my out put is this
����
if any one know about this please help me.
You have to decode JSON response from the body like this:
var_dump(json_decode($response->getBody(), true));
Then you will get an array with proper response :)
e.g.:
array(1) { ["status"]=> int(21002) }
I'm trying to connect to Yelp's API, currently using ZF2 and ZendOAuth. I don't know why I'm getting a 404. Here is the raw request and response headers.
POST /v2/search?term=tacos&location=sf HTTP/1.1
Host: api.yelp.com
Connection: close
Accept-Encoding: gzip, deflate
User-Agent: Zend\Http\Client
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth realm="",oauth_consumer_key="<key>",oauth_nonce="<nonce>",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1387401249",oauth_version="1.0",oauth_token="<token>",oauth_signature="<signature>"
HTTP/1.1 404 Not Found
Date: Wed, 18 Dec 2013 21:14:09 GMT
Server: Apache
X-Node: web41, api_com
Content-Length: 8308
Vary: User-Agent
Connection: close
Content-Type: text/html; charset=UTF-8
X-Mode: rw
X-Proxied: lb1
Does that request look like it should connect somewhere?
Here's some code.
$accessToken = new \ZendOAuth\Token\Access();
$accessToken->setToken('<token>');
$accessToken->setTokenSecret('<secret>');
$host = 'http://' . $_SERVER['HTTP_HOST'];
$config = array(
'consumerKey'=>'<key>',
'consumerSecret'=>'<secret>',
);
$client = $accessToken->getHttpClient($config);
$client->setUri('http://api.yelp.com/v2/search?term=tacos&location=sf');
$client->setMethod('POST');
$adapter = new \Zend\Http\Client\Adapter\Socket();
$client->setAdapter($adapter);
$response = $client->send();
$result = $response->getBody();
All the examples of OAuth I've seen get the access token with a request token, but Yelp already gave me the token and secret, so I'm trying to construct it manually.
Update:
Changing
$client->setMethod('POST');
to
$client->setMethod('GET');
is the first step, but the parameters can't be added manually to the URL, they have to be added with setParameterGet();. So here's my updated working code.
$accessToken = new \ZendOAuth\Token\Access();
$accessToken->setToken('<token>');
$accessToken->setTokenSecret('<secret>');
$host = 'http://' . $_SERVER['HTTP_HOST'];
$config = array(
'consumerKey'=>'<key>',
'consumerSecret'=>'<secret>',
);
$client = $accessToken->getHttpClient($config);
$client->setUri('http://api.yelp.com/v2/search');
$client->setMethod('GET');
$params = array('term'=>'tacos', 'location'=>'sf');
$client->setParameterGet($params);
$adapter = new \Zend\Http\Client\Adapter\Socket();
$client->setAdapter($adapter);
$response = $client->send();
$result = $response->getBody();
That api requires GET method. So change:
$client->setMethod('POST');
To:
$client->setMethod('GET');
And try again )
I am trying to use Crocodoc api with the following code to get the status.
$croco = new Crocodoc();
$uuids = "786e072b-981c-4d2a-8e80-80e215f1f7c2";
echo "\n\nchecking status of : ", $uuids;
$status = $croco->getStatus($uuids);
echo "\n\nstatus is : ", $status;
class Crocodoc {
public $api_key = 'HPUd6LZXg5174TAENbvBcx30';
public $api_url = 'https://crocodoc.com/api/v2/';
public function getStatus($uuids){
$url = $this->api_url.'document/status';
$token = $this->api_key;
$dataStr = '?token='.$token.'&uuids='.$uuids;
// this is a GET request
$output = $this->doCurlGet($url, $dataStr);
return $output;
}
}
I don't get the status and no error. What is wrong or it does not work in evaluation mode. Right now I am using it local with XAMPP, can that be a problem?
What doCurlGet does?
Because the request (and response) is fine:
HTTP/1.1 200 OK
Server: nginx/1.2.0
Date: Thu, 24 May 2012 10:11:27 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
[
{
"uuid": "786e072b-981c-4d2a-8e80-80e215f1f7c2",
"viewable": true,
"status": "DONE"
}
]
You might try with a real curl, like:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "/* generated url to crocodoc */");
$data = curl_exec($ch);
curl_close($ch);
Or directly:
$data = file_get_contents('/* generated url to crocodoc */');
Edit:
Just tried this code, and it works fine:
$croco = new Crocodoc();
$uuids = "786e072b-981c-4d2a-8e80-80e215f1f7c2";
$status = $croco->getStatus($uuids);
var_dump($status);
class Crocodoc {
public $api_key = 'HPUd6LZXg5174TAENbvBcx30';
public $api_url = 'https://crocodoc.com/api/v2/';
public function getStatus($uuids){
$url = $this->api_url.'document/status';
$token = $this->api_key;
$dataStr = '?token='.$token.'&uuids='.$uuids;
// this is a GET request
return file_get_contents($url.$dataStr);
}
}