I get an object with nested arrays of nested objects when I make an API call. In the SDK I have the header set to accept: application/json. I am wondering why I am getting objects and arrays back?
Here is a partial part of the response:
PayPal\Api\CreditCard Object
(
[_propMap:PayPal\Common\PPModel:private] => Array
(
[type] => amex
[number] => xxxxxxxxxxx0005
[expire_month] => 5
[expire_year] => 2015
[cvv2] => 1234
[first_name] =>
[last_name] =>
[payer_id] => 3zIVtTFQ7UdKjP5mssjtzoUo6NvrsExl466oPC4Mm8nwOjI6BS
[id] => CARD-35X96613EN689504VKKCA4RA
[state] => ok
[valid_until] => 2015-06-01T00:00:00Z
[create_time] => 2013-11-13T23:41:56Z
[update_time] => 2013-11-13T23:41:56Z
[links] => Array
(
[0] => PayPal\Api\Links Object
(
[_propMap:PayPal\Common\PPModel:private] => Array
(
[href] => https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-35X96613EN689504VKKCA4RA
[rel] => self
[method] => GET
)
)
[1] => PayPal\Api\Links Object
... and so on
Code that creates this
public static function get($creditCardId, $apiContext = null) {
if (($creditCardId == null) || (strlen($creditCardId) <= 0)) {
throw new \InvalidArgumentException("creditCardId cannot be null or empty");
}
$payLoad = "";
if ($apiContext == null) {
$apiContext = new ApiContext(self::$credential);
}
$call = new PPRestCall($apiContext);
print_r($call);
die;
$json = $call->execute(array('PayPal\Rest\RestHandler'), "/v1/vault/credit-card/$creditCardId", "GET", $payLoad);
$ret = new CreditCard();
$ret->fromJson($json);
return $ret;
}
Ok, so thank you Machavity for the help. The issue was that in the function that I posted above, it takes the JSON response and converts it to some wierd object thing with:
$ret->fromJson($json);
I removed that line and I now get JSON. I still wonder why having that object I intitially posted would be helpful and where it could be used. I also wonder why the SDK documentation doesn't explicitly state that the SDK does not return JSON as the final format. I feel it would save a lot of time if PayPal informed a developer that the response gets converted to an object, so we wouldn't have to search through thousands of lines of code to figure it out.
It's likely the SDK is accepting JSON on the communications layer and then running json_decode to pass you back an object you can work with. My own API system converts the response back into a PHP array.
json_decode( $call->execute(array('PayPal\Rest\RestHandler'), "/v1/vault/credit-card/$creditCardId", "GET", $payLoad) );
Related
I tried to do my first API calls which worked finally with help from this great users here in this community. Thanks again. I want to choose data[1] or the currency with symbol. So i could use a $variable from my CMS. Maybe someone can show me a way how i can change this call to symbol. Here is my API call.
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest";
$headers = [
'Accepts: application/json',
'X-CMC_PRO_API_KEY: ___YOUR_API_KEY_HERE___'
];
$request = "{$url}"; // create the request URL
$curl = curl_init(); // Get cURL resource
// Set cURL options
curl_setopt_array($curl, array(
CURLOPT_URL => $request, // set the request URL
CURLOPT_HTTPHEADER => $headers, // set the headers
CURLOPT_RETURNTRANSFER => 1 // ask for raw response instead of bool
));
$response = curl_exec($curl); // Send the request, save the response
$json = json_decode($response);
curl_close($curl); // Close request
$price = $json->data[1]->quote->USD->price; echo $price;
You get the data block IDs with array_column(), then you get the symbol's data block ID with array_search():
$data_ids = array_column($json->data, 'symbol');
$symbol_data_id = array_search('ETH', $data_ids);
$price = $json->data[$symbol_data_id]->quote->USD->price;
Or as an oneliner:
$price = $json->data[array_search('ETH', array_column($json->data, 'symbol'))]->quote->USD->price;
LATER UPDATE: OK, let me elaborate on this. Step by step:
You need a proper URL to acces the API. For this you need the API documentation. Your original question mentioned
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest";
while for your comment question you need something like
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/info?symbol=ETH";
A proper URL will give you a JSON response structured according to its purpose. You have this part ironed out, so I'll not insist on this. From your question text:
$headers = [
'Accepts: application/json',
'X-CMC_PRO_API_KEY: 1b58ff56-58b2-4fd0-b184-f9c3dd4ff106',
];
$request = "{$url}"; // create the request URL
$curl = curl_init(); // Get cURL resource
// Set cURL options
curl_setopt_array($curl, [
CURLOPT_URL => $request, // set the request URL
CURLOPT_HTTPHEADER => $headers, // set the headers
CURLOPT_RETURNTRANSFER => 1, // ask for raw response instead of bool
]);
$response = curl_exec($curl); // Send the request, save the response
$json = json_decode($response);
curl_close($curl); // Close request
Then you have to decide how to use the response. For me, the fastest way is to look at its structure (var_dump($json) or print_r($json)). Which will give something like this (the original question):
stdClass Object
(
[status] => stdClass Object
(
[timestamp] => 2021-11-06T18:37:59.447Z
[error_code] => 0
[error_message] =>
[elapsed] => 22
[credit_count] => 1
[notice] =>
[total_count] => 7060
)
[data] => Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Bitcoin
[...]
)
[1] => stdClass Object
(
[id] => 1027
[name] => Ethereum
[symbol] => ETH
[slug] => ethereum
[...]
[quote] => stdClass Object
(
[USD] => stdClass Object
(
[price] => 4445.0743486785
[volume_24h] => 14137477206.072
[volume_change_24h] => -9.6622
[percent_change_1h] => 0.2898806
[percent_change_24h] => -1.29677209
[percent_change_7d] => 3.13286959
[percent_change_30d] => 23.49191199
[percent_change_60d] => 28.79913805
[percent_change_90d] => 48.37310902
[market_cap] => 525560956659.07
[market_cap_dominance] => 19.5198
[fully_diluted_market_cap] => 525560956659.07
[last_updated] => 2021-11-06T18:37:03.000Z
)
)
)
[2] => stdClass Object [...]
or this (the question in the comment):
stdClass Object
(
[status] => stdClass Object
(
[timestamp] => 2021-11-06T18:03:05.201Z
[error_code] => 0
[error_message] =>
[elapsed] => 12
[credit_count] => 1
[notice] =>
)
[data] => stdClass Object
(
[ETH] => stdClass Object
(
[id] => 1027
[name] => Ethereum
[symbol] => ETH
[category] => coin
[description] => Ethereum (ETH) is a cryptocurrency . Users are able to generate ETH through the process of mining. Ethereum has a current supply of 118,233,336.749. The last known price of Ethereum is 4,424.33123326 USD and is down -1.39 over the last 24 hours. It is currently trading on 4537 active market(s) with $14,138,162,060.93 traded over the last 24 hours. More information can be found at https://www.ethereum.org/.
[...]
[platform] =>
[date_added] => 2015-08-07T00:00:00.000Z
[twitter_username] => ethereum
[is_hidden] => 0
)
)
)
So data is a property of the $json object.
In the first case, data is an array and its structure suggests using array functions to retrieve specific data.
In the second case, data and ETH are objects, while description is a property of ETH. Which allows me to get the description using object syntax
$description = $json->data->ETH->description;
For example a request like
$request = new FacebookRequest($session, 'GET','/me/accounts?fields=id,name,access_token');
$response = $request->execute();
$arrayResult = $response->getGraphObject()->asArray();
print_r($arrayResult);
returns
Array (
[data] => Array (
[0] => stdClass Object (
[id] => 01010011100001111000111 #it's a fake id
[name] => MyAwesomePageName #And a fake name
)
)
[paging] => stdClass Object (
[next] => https://graph.facebook.com/v2.0/01010011100001111000111/accounts?fields=id,name&access_token=RanDoMAndFaaKKeEACCessToKen&limit=5000&offset=5000&__after_id=enc_IdOnOTKnoWWhAtThiSIs
)
)
Thats is.
I would like to retrieve all the response in array and without theses stdClass objects.
Just like it was in the previous version of their api.
Thanks.
An easier way might be to grab the raw JSON from the $response and decode it yourself:
$request = new FacebookRequest($session, 'GET', '/me/accounts?fields=id,name,access_token');
$response = $request->execute();
$array = json_decode($response->getRawResponse(), true);
print_r($array);
Update
As of PHP SDK 5.0+ you can use getDecodedBody() on the FacebookResponse object (this does the JSON decoding for you and returns an array).
$fb = new Facebook([...]);
$response = $fb->get('/me', '{access-token}');
$array = $response->getDecodedBody();
The Facebook SDK's asArray() method is limited as you've discovered. However, you can manually convert an object to an array using the get_object_vars( $object ); function. In your example, you can do something like:
$array = get_object_vars( $arrayResult['data'][0] );
This will convert the page Object into an array. The function isn't recursive, so you'll need to convert each object to an array.
You can use a recursive function like this:
function object_to_array($obj) {
$arr = array();
if($obj instanceOf GraphObject){
if(is_scalar($obj->asArray()) )
$arr = $obj->asArray();
else{
foreach ($obj->getPropertyNames() as $propName) {
$arr[$propName] = object_to_array($obj->getProperty($propName));
}
}
}else if(is_array($obj)){
foreach ($obj as $propKey => $propValue) {
$arr[$propKey] = object_to_array($obj[$propValue]);
}
}else $arr = $obj;
return $arr;
}
Just use json_decode($arrayResult) to get the JSON output. The output you are getting is simply a php data structure.
We can simply do json_encode and decode as an Array
$arrayResult = json_decode(json_encode($appreq['data'][0]),true);
sample output
Array
(
[application] => Array
(
[name] => Test App
[namespace] => app-test-app
[id] => 988798798798
)
[created_time] => 2015-02-17T08:42:14+0000
[data] => action=acceptit
[from] => Array
(
[id] => 987989798
[name] => TestUser
)
[message] => I have sent 1 Request
[to] => Array
(
[id] => 98098090
[name] => NameAjax
)
[id] => 345423452345_34523452453
)
I'm using the tumblr API and the following code:
$var = xhttp::toQueryArray($response['body']);
print_r($var);
This print on the screen the following:
Array ( [{"meta":{"status":200,"msg":"OK"},"response":{"user":{"name":"lukebream","likes":0,"following":8,"default_post_format":"html","blogs":[{"name":"lukebream","url":"http:\/\/lukebream.tumblr.com\/","followers":5,"primary":true,"title":"Untitled","admin":true,"queue":0,"ask":false,"tweet":"N"}]}}}] => )
How can I access the individual elements and assign them to variables?
Here is what I have finished with:
$tumblr->set_token($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);
$data = array();
$data['post'] = array();
$response = $tumblr->fetch('http://api.tumblr.com/v2/user/info', $data);
if($response['successful']) {
echo $response['json']['response']['url'];
} else {
echo "api call failed. {$response[body]}<br><br>";
}
It's called JSON, you can parse it using json_decode()
Usage Example :
//I used file_get_contents() to keep things simple
$jsonData = file_get_contents("http://api.tumblr.com/v2/blog/lukebream.tumblr.com/info?api_key=<api_key_here>");
The $jsonData contains :
{
"meta":{
"status":200,
"msg":"OK"
},
"response":{
"blog":{
"title":"Untitled",
"posts":61,
"name":"lukebream",
"url":"http:\/\/lukebream.tumblr.com\/",
"updated":1321830278,
"description":"",
"ask":false,
"likes":0
}
}
}
after it goes through json_decode(), we get a PHP object, so :
$obj = json_decode($jsonData);
will return :
stdClass Object
(
[meta] => stdClass Object
(
[status] => 200
[msg] => OK
)
[response] => stdClass Object
(
[blog] => stdClass Object
(
[title] => Untitled
[posts] => 61
[name] => lukebream
[url] => http://lukebream.tumblr.com/
[updated] => 1321830278
[description] =>
[ask] =>
[likes] => 0
)
)
)
Then you can access the data like with any other object.
You can also use json_decode($str, TRUE): this will return an ARRAY instead of an object, much easier to play with!
I am ignorant when it comes to SOAP. I am performing a web service call:
<?php
// define the SOAP client using the url for the service
$client = new soapclient('http://www.xignite.com/xMetals.asmx?WSDL', array('trace' => 1));
// create an array of parameters
$param = array(
'Type' => "XAU",
'Currency' => "USD");
// call the service, passing the parameters and the name of the operation
$result = $client->GetLastRealTimeMetalQuote($param);
// assess the results
if (is_soap_fault($result)) {
echo '<h2>Fault</h2><pre>';
print_r($result);
echo '</pre>';
} else {
echo '<h2>Result</h2><pre>';
print_r($result);
echo '</pre>';
}
?>
and when I run the script i get:
Result
stdClass Object
(
[GetLastRealTimeMetalQuoteResult] => stdClass Object
(
[Outcome] => Success
[Identity] => IP
[Delay] => 0.006
[Symbol] => XAUUSDO
[Type] => XAU
[Currency] => USD
[Date] => 8/1/2011
[Time] => 11:18:48 PM
[Rate] => 1618.88500977
[Bid] => 1618.55004883
[BidTime] => 11:18:48 PM
[Ask] => 1619.2199707
[AskTime] => 11:18:48 PM
)
)
How do I separate the [Bid] out from the rest of the result and store it in a variable.
Or better yet how can I pull out the array?
Don't let the stdClass object mix you up - this is simply an array that is represented with object notation. So, $result['GetLastRealTimeMetalQuoteResult']['Bid'] (a normal associative array) becomes $result->GetLastRealTimeMetalQuoteResult->Bid - same values, just a different notation.
You get stdClass objects when a value is typecast into an object, which the SOAP library does. See: http://php.net/manual/en/reserved.classes.php For some more detail about stdClass, check out this article: http://krisjordan.com/dynamic-properties-in-php-with-stdclass
If you'd like to convert the stdClass to an array, unfortunately you'll have to use a little function:
function objToArray($obj=false) {
if (is_object($obj))
$obj= get_object_vars($obj);
if (is_array($obj)) {
return array_map(__FUNCTION__, $obj);
} else {
return $obj;
}
}
$somevar = $result->GetLastRealTimeMetalQuoteResult->Bid;
I am experimenting with differnt API's of websites right now because I am building my own API for site, On bebo.com through there API they have a php cient which passes a key and secret that the owner of the app has. you then have a client library with a bunch of methods/functions you can call, all of the methods work like this:
public function score_getHigh($uid='', $name='') {
return $this->execute('score.getHigh', array('member_id' => $uid, 'name' => $name));
}
You can see they all just pass in a name of a function and put the params into an array and pass it through the execute(METHOD-NAME, METHOD PARAMS) function. This function then runs code like this
//execute function
//flatten array
foreach ($params as $k => $v) {
if (is_array($v)) {
$params[$k] = implode(',', $v);
}
}
To make a list of all the functions and params to run, it then POST or GET this to the API page with CURL and this is the result that comes back below in my browser if I visit the page myself in a browser instead of letting curl post it then I view the page source of the web browser it shows this array just how I posted it in the browser,
Array
(
[error_code] => 102
[error_msg] => Session key invalid or no longer valid
[request_args] => Array
(
[0] => Array
(
[key] => v
[value] => 1.0
)
[1] => Array
(
[key] => api_key
[value] => Qnw1Moc22Y9m3XY5zUZohbxiwfkURaPJpN3m
)
[2] => Array
(
[key] => method
[value] => friends.get
)
[3] => Array
(
[key] => call_id
[value] => 1262417906.33
)
[4] => Array
(
[key] => sig
[value] => 18b8592f383a5f0abc332745284a0e99
)
)
)
So finally the question here, What kind of response is this, it's not JSON and I don't think it is XML, what would this be called and the script that is trying to get this result with CURL, how can it process this back into something to work with?
From your PHP script, you should be able to do something like this:
$foo = $bebo->score_getHigh(...);
echo $foo['error_code']; // Should output 102 in this case
The response that you posted looks like the output of PHP's serialize function. That would make sense if you use Bebo's PHP client to make a request and then printed the resulting object. Bebo's service is actually returning XML to you when you make your request, as demonstrated by the example below.
$ curl http://apps.bebo.com/restserver.php?\
v=1.0&api_key=Qnw1Moc22Y9m3XY5zUZohbxiwfkURaPJpN3m\
&method=friends.get&call_id=1262417906.33&\
sig=18b8592f383a5f0abc332745284a0e99
<error_response>
<error_code>102</error_code>
<error_msg>Session key invalid or no longer valid</error_msg>
<request_args list="true">
<arg>
<key>v</key>
<value>1.0</value>
</arg>
<arg>
<key>api_key</key>
<value>Qnw1Moc22Y9m3XY5zUZohbxiwfkURaPJpN3m</value>
</arg>
<arg>
<key>method</key>
<value>friends.get</value>
</arg>
<arg>
<key>call_id</key>
<value>1262417906.33</value>
</arg>
<arg>
<key>sig</key>
<value>18b8592f383a5f0abc332745284a0e99</value>
</arg>
</request_args>
</error_response>