Extract Required info from json nested nested loops - php

I am using php to fetch live rates for cryptocurrency from coin market cap api. Here is the response that i get from the api. I want to extract the USD price from this nested response. I tried this :
$rate = json_decode($response,true);
echo $rate['data'][0]['quotes'][0]['USD'][0];
But it didn't worked. The json response that i got is :
{
"status": {
"timestamp": "2020-09-26T12:59:24.147Z",
"error_code": 0,
"error_message": null,
"elapsed": 13,
"credit_count": 1,
"notice": null
},
"data": {
"BTC": {
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"num_market_pairs": 9251,
"date_added": "2013-04-28T00:00:00.000Z",
"tags": [
"mineable",
"pow",
"sha-256",
"store-of-value",
"state-channels"],
"max_supply": 21000000,
"circulating_supply": 18500450,
"total_supply": 18500450,
"is_active": 1,
"platform": null,
"cmc_rank": 1,
"is_fiat": 0,
"last_updated": "2020-09-26T12:58:38.000Z",
"quote": {
"USD": {
"price": 10707.7229962,
"volume_24h": 20866014910.9822,
"percent_change_1h": -0.156013,
"percent_change_24h": 0.675761,
"percent_change_7d": -2.97789,
"market_cap": 198097693905.04828,
"last_updated": "2020-09-26T12:58:38.000Z"
}
}
}
}
}
Thank you guys for your help!

Try this way if you need to grab the USD price only of BTC,
echo $rate['data']['BTC']['quote']['USD']['price'];
Otherwise need to loop through the API response and grab the value from it but the index path ['quote']['USD']['price'] should be more or less the same as I pointed.
DEMO: https://3v4l.org/gi7jB

You need to take care of indexes. When using associative arrays (hashmaps) you can not use numeric indexes.
foreach ($rate['data'] as $currency => $currencyData) {
echo "$currency: {$currencyData['quote']['USD']['price']}\n";
}
BTC: 10707.7229962

Related

How to get values from nested json in php [duplicate]

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 1 year ago.
I have this json file
{
"success": true,
"data": {
"total": "2",
"returned": 2,
"start": 0,
"limit": 10,
"transactions": [
{
"id": "16393567",
"type": "Credit",
"currency": "BTC",
"amount": "0.00019449",
"when": "2021-09-03 10:27:48",
"rental": "3411209",
"rig": "205363",
"status": "Pending",
"pending_seconds": "716202"
},
{
"id": "16377905",
"type": "Credit",
"currency": "BTC",
"amount": "0.00000203",
"when": "2021-09-01 11:42:47",
"rental": "3408621",
"rig": "205363",
"status": "Cleared",
"pending_seconds": 0
}
]
}
}
I am able to get values under data with this code
$jsonCont = file_get_contents('temp.json');
$content = json_decode($jsonCont, true);
$rig_detail= $content['data']['total'];
$rig_detail= $content['data']['returned'];
$rig_detail= $content['data']['start'];
$rig_detail= $content['data']['limit'];
My problem exists where I try and get data from "transactions" I have tried
$rig_detail= $content['data']['transactions']['id'];
This however does not give me what I expected. What do I need to do to access the data within the transactions section?
the are more elements in $content['data']['transactions'], so it is an array.
Try something like this:
$rig_detail= $content['data']['transactions'][0]['id'];

Duplicate fields/values from JSON object array in php

I am working on a website in which I want to remove duplicate fields from JSON object array.
The JSON object array which I have is:
"rental_rates": [{
"rate_id": 170,
"uuid": "a3a14d20-63d1-11e8-b047-89e5d3a9513d",
"owner_id": 38,
"item_id": 394,
"name": "daily",
"term": "daily",
"currency": "dollars",
"rate": "56.00",
"min_charge": "56.00",
"created_at": "2018-05-30 06:20:43",
"updated_at": "2018-05-30 06:21:07"
}, {
"rate_id": 172,
"uuid": "a3a1c500-63d1-11e8-8740-8925bbb8ada8",
"owner_id": 38,
"item_id": 394,
"name": "weekly",
"term": "weekly",
"currency": "dollars",
"rate": "677.00",
"min_charge": "56.00",
"created_at": "2018-05-30 06:21:00",
"updated_at": "2018-05-30 06:21:07"
}],
The code which I am using in order to pull fields/values form JSON object array is:
foreach ($data['item']->rental_rates as $rental_rate)
{
echo '<span class="rental_term" style="text-align:right">'."minimum".'</span>';
echo '<span class="rental_price" style="text-align:right">$'.floatval($rental_rate->min_charge).'</span><br>';
}
The above code is pulling the following data and I want only one to be shown.
minimum $56
minimum $56
Problem Statement:
I am wondering what changes I need to make in the foreach loop so it pull only one field and value like this,
minimum $56
Two ways. Store what has already been displayed and check for it:
$shown = array();
foreach ($data['item']->rental_rates as $rental_rate)
{
if(!in_array($rental_rate->min_charge, $shown)) {
$shown[] = $rental_rate->min_charge;
echo '<span class="rental_term" style="text-align:right">'."minimum".'</span>';
echo '<span class="rental_price" style="text-align:right">$'.floatval($rental_rate->min_charge).'</span><br>';
}
}
Or create an array indexed by the min_value so there will only ever be one (only works on objects as of PHP >= 7.0.0):
$rates = array_column($data['item']->rental_rates, null, 'min_charge');
foreach $rates as $rental_rate)
{
echo '<span class="rental_term" style="text-align:right">'."minimum".'</span>';
echo '<span class="rental_price" style="text-align:right">$'.floatval($rental_rate->min_charge).'</span><br>';
}
For PHP < 7.0.0, decode the JSON as an array passing true as the second argument and use $data['item']['rental_rates'] and $rental_rate['min_charge'] in the code above instead.

Need help using array/json in php for coinmarketcap api

I'm trying to make a simple website that uses the coinmarketcap api to track current cryptocurrency prices, and the code below works but it doesn't account for when currencies overtake each other.
<?php
$tick = file_get_contents('https://api.coinmarketcap.com/v1/ticker/');
$url = $tick;
echo $url;
$json = file_get_contents($url);
$data = json_decode($tick, TRUE); //decodes in associative array
$ethusd = $data[1]['price_usd'];
echo $ethusd;
?>
And this is the json being decoded
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "16474.4",
"price_btc": "1.0",
"24h_volume_usd": "13440600000.0",
"market_cap_usd": "275760451140",
"available_supply": "16738725.0",
"total_supply": "16738725.0",
"max_supply": "21000000.0",
"percent_change_1h": "-2.32",
"percent_change_24h": "-5.68",
"percent_change_7d": "24.41",
"last_updated": "1513187054"
},
{
"id": "ethereum",
"name": "Ethereum",
"symbol": "ETH",
"rank": "2",
"price_usd": "684.996",
"price_btc": "0.04138",
"24h_volume_usd": "4731760000.0",
"market_cap_usd": "65976663404.0",
"available_supply": "96316859.0",
"total_supply": "96316859.0",
"max_supply": null,
"percent_change_1h": "-5.62",
"percent_change_24h": "12.04",
"percent_change_7d": "56.0",
"last_updated": "1513187055"
},
{
"id": "bitcoin-cash",
"name": "Bitcoin Cash",
"symbol": "BCH",
"rank": "3",
"price_usd": "1594.38",
"price_btc": "0.0963151",
"24h_volume_usd": "1286400000.0",
"market_cap_usd": "26871042768.0",
"available_supply": "16853600.0",
"total_supply": "16853600.0",
"max_supply": "21000000.0",
"percent_change_1h": "-3.9",
"percent_change_24h": "1.8",
"percent_change_7d": "8.88",
"last_updated": "1513187076"
},
etc.
Since ether is the second highest currency in the json it works for now, but if it moves it wouldn't. So is there a way for me to do something like $data[something that specifies ether]['price_usd'] instead? Apologies in advance for any PHP ignorance, I know very little about PHP/arrays/etc and just started working with it a few days ago.
I played a little bit with their API and you can fetch only 1 currency by appending the slug of the currency in the url:
example https://api.coinmarketcap.com/v1/ticker/ethereum/
so your endpoint becomes https://api.coinmarketcap.com/v1/ticker/{slug}/
/!\ Be aware that this endpoint still sends you a JSON array so you have to take the first index with $data[0].
Your code becomes :
<?php
$slug = 'ethereum'; // find all at https://files.coinmarketcap.com/generated/search/quick_search.json
$tick = file_get_contents('https://api.coinmarketcap.com/v1/ticker/'.$slug.'/');
$url = $tick;
echo $url;
$json = file_get_contents($url);
$data = json_decode($tick, TRUE); //decodes in associative array
$ethusd = $data[0]['price_usd'];
echo $ethusd;
?>
All slugs are listed here https://files.coinmarketcap.com/generated/search/quick_search.json
PS: API docs are here https://coinmarketcap.com/api/ but it doesn't mention the slug endpoint
What I understand here is that you want to get the price_usd only for ethereum id, to do so you can use array_columns to extract all ids as one array and then search the index of 'ethereum':
$key_ethereum = array_search('ethereum', array_column($data, 'id'));
// array_column($data, 'id') => ['bitcoin', 'ethereum', 'bitcoin-cash']
// array_search('ethereum', ['bitcoin', 'ethereum', 'bitcoin-cash']); => 1
echo $data[ $key_ethereum ]['price_usd'];
Live Demo
Hope this helps

How to loop through JSON array using PHP

My PHP code:
$obj = json_decode($data);
print $obj->{'name'};
While it works for non-arrays, I can't for the life of me figure out how to print all the values within the "Reviews" Array.
What I would like to do is to loop through this response, probably with forreach(), resulting in a list containing the rating and excerpt for each review in the response.
Any guidance / direction is greatly appreciated..
Below is the JSON I'm working with. (it is the response from the Yelp API).
{
"is_claimed": true,
"rating": 4.5,
"mobile_url": "http://m.yelp.com/biz/economy-paint-and-collision-riverside",
"rating_img_url": "http://s3-media2.ak.yelpcdn.com/assets/2/www/img/99493c12711e/ico/stars/v1/stars_4_half.png",
"review_count": 19,
"name": "Economy Paint & Collision",
"snippet_image_url": "http://s3-media3.ak.yelpcdn.com/photo/ZOzoahw0Go_DEPLvxCaP_Q/ms.jpg",
"rating_img_url_small": "http://s3-media2.ak.yelpcdn.com/assets/2/www/img/a5221e66bc70/ico/stars/v1/stars_small_4_half.png",
"url": "http://www.yelp.com/biz/economy-paint-and-collision-riverside",
"reviews": [
{
"rating": 3,
"excerpt": "The Good:\nDennis quoted me a price over the phone about 1 month before I took my wifes 2010 Escalade in for repairs and when I took it in he gave me the...",
"time_created": 1357010247,
"rating_image_url": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/34bc8086841c/ico/stars/v1/stars_3.png",
"rating_image_small_url": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/902abeed0983/ico/stars/v1/stars_small_3.png",
"user": {
"image_url": "http://s3-media3.ak.yelpcdn.com/photo/mIsU7ugYd88lLA-XL2q1Cg/ms.jpg",
"id": "V9MDZvEBv-tBTF4YIoc7mg",
"name": "Sydney H."
},
"rating_image_large_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/e8b5b79d37ed/ico/stars/v1/stars_large_3.png",
"id": "HfOhzLIlJoUKSKU8euclqA"
},
{
"rating": 5,
"excerpt": "Dennis and his team did an amazing job on the roof of my fiancee's 2002 Acura RSX after years of living by the beach in San Francisco had mostly rusted...",
"time_created": 1354741952,
"rating_image_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
"rating_image_small_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
"user": {
"image_url": "http://s3-media3.ak.yelpcdn.com/photo/ZOzoahw0Go_DEPLvxCaP_Q/ms.jpg",
"id": "kOqCnCjYn0EbAhtH1tfjcw",
"name": "Jason H."
},
"rating_image_large_url": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
"id": "YzZg1LX6zeRaurq9tYUcMw"
},
{
"rating": 5,
"excerpt": "It's been a year since I had my car painted here, and I gotta say: It still looks just as good as it did when I first picked it up. You would never know...",
"time_created": 1361043626,
"rating_image_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
"rating_image_small_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
"user": {
"image_url": "http://s3-media1.ak.yelpcdn.com/photo/58coTtu1x5riHSgFEAQsfw/ms.jpg",
"id": "kVrW3138d5VL-AZ97wFF4A",
"name": "Jeanne M."
},
"rating_image_large_url": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
"id": "r5WtlQVMXiIMBR6S3N7RZw"
}
],
"phone": "9517870227",
"snippet_text": "Dennis and his team did an amazing job on the roof of my fiancee's 2002 Acura RSX after years of living by the beach in San Francisco had mostly rusted...",
"image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/kodoEcmgHRG61pPaWRndbw/ms.jpg",
"categories": [
[
"Body Shops",
"bodyshops"
],
[
"Auto Repair",
"autorepair"
]
],
"display_phone": "+1-951-787-0227",
"rating_img_url_large": "http://s3-media4.ak.yelpcdn.com/assets/2/www/img/9f83790ff7f6/ico/stars/v1/stars_large_4_half.png",
"id": "economy-paint-and-collision-riverside",
"is_closed": false,
"location": {
"city": "Riverside",
"display_address": [
"2548 Rubidoux Blvd",
"Riverside, CA 92509"
],
"geo_accuracy": 8,
"postal_code": "92509",
"country_code": "US",
"address": [
"2548 Rubidoux Blvd"
],
"coordinate": {
"latitude": 34.0132437,
"longitude": -117.3923804
},
"state_code": "CA"
}
}
You are probably having trouble because reviews is an array and you are trying to access it as a JSON object.
$obj = json_decode($data, TRUE);
for($i=0; $i<count($obj['reviews']); $i++) {
echo "Rating is " . $obj['reviews'][$i]["rating"] . " and the excerpt is " . $obj['reviews'][$i]["excerpt"] . "<BR>";
}
I'm not sure what exactly you want but I guess you want print it just for debugging right now. You can try with print_r($obj); and var_dump($obj); - they must print something, especially var_dump().
When you see the data, you can easily edit function a little bit, so you can do for instance print_r($obj->reviews) or print_r($obj['reviews']), depending if $obj is object or array.
You can use var_dump or print_r.
<?php
$decodedJSON = json_decode($jsonData);
// Put everyting to the screen with var_dump;
var_dump($decodedJSON);
// With print_r ( useful for arrays );
print_r($decodedJSON);
// List just review ratings with foreach;
foreach($decodedJSON['reviews'] as $review){
echo $review['rating'];
}
?>
Here using objects example (to read reviews...raiting):
$jsonObject = json_decode($data);
foreach ($jsonObject->reviews as $data) {
echo $data->rating;
}

Json Traverse Problem, not able to traverse values

I m getting the below return from ajax call but not able to traverse it please please help.
{
"1": {
"tel1": null,
"status": "1",
"fax": "",
"tel2": null,
"name": "sh_sup1",
"country": "Anguilla",
"creation_time": "2010-06-02 14:09:40",
"created_by": "0",
"Id": "85",
"fk_location_id": "3893",
"address": "Noida",
"email": "sh_sup1#shell.com",
"website_url": "http://www.noida.in",
"srk_main_id": "0"
},
"0": {
"tel1": "Ahemdabad",
"status": "1",
"fax": "",
"tel2": "Gujrat",
"name": "Bharat Petro",
"country": "India",
"creation_time": "2010-05-31 15:36:53",
"created_by": "0",
"Id": "82",
"fk_location_id": "3874",
"address": "THIS is test address",
"email": "bp#india.com",
"website_url": "http://www.bp.com",
"srk_main_id": "0"
},
"count": 2
}
You can do it very easily:
for(i = 0; i < msg.count; i++) {
alert(msg[i]['name']);
}
But the structure of your JSON object is not that good for several reasons:
It does not reflect the structure of the actual data
With this I mean, that you actually have an array of objects. But in your JSON object the elements of the array are represented as properties of an object.
You have invalid JavaScript object property names.
Properties for objects in JavaScript are not allowed to start with numbers. But with msg = { "1": {...}} you have a number as property.
Fortunately it is not that bad because you can access this property with "array like" access msg["1"] (instead of the "normal way", msg.1). But I would consider this as bad practice and avoid this as much as possible.
Hence, as Matthew already proposes, it would be better to remove the count entry from the array on the server side, before you sent it to the client. I.e. you should get a JSON array:
[{
"tel1": "Ahemdabad",
"status": "1",
// etc.
},
{
"tel1": null,
"status": "1",
// etc.
}]
You don't need count as you can get the length of the array with msg.length and you can traverse the array with:
for(var i in msg) {
alert(msg[i].name);
}

Categories