Browse json and count values - php

Good night.
I'm trying to access all of the availableForExchange values ​​on the return of a page below:
[
{
"code":"18707498",
"date":"2019-01-23T16:58:01",
"totalPriceInCents":14450,
"orderTotalPriceInCents":14450,
"status":"PGTO_NAO_CONFIRMADO",
"availableForExchange":false,
"paymentType":"CREDIT_CARD",
"installmentValueInCents":7225,
"installmentsNumber":2,
"paymentSummaries":[
{
"paymentType":"CREDIT_CARD",
"installmentsNumber":2,
"installmentValueInCents":7225,
"valueInCents":14450
}
],
"hasGiftCard":false
},
{
"code":"019741817156",
"date":"2017-06-11T19:09:06",
"totalPriceInCents":19110,
"orderTotalPriceInCents":19110,
"status":"ENTREGA_EFETUADA",
"availableForExchange":false,
"paymentType":"CREDIT_CARD",
"installmentValueInCents":9555,
"installmentsNumber":2,
"paymentSummaries":[
{
"paymentType":"CREDIT_CARD",
"installmentsNumber":2,
"installmentValueInCents":9555,
"valueInCents":19110
}
],
"hasGiftCard":false
}
]
I have already tried the following ways:
$data = curl_exec($ch);
$json = json_decode($data, true);
$str = $json['availableForExchange'];
print_r($str);
I need to access all values ​​of: availableForExchange, search for true values ​​and count (if true),
and save to a variable.

what you want to do is to filter the $json (it is an array)
$found = array_filter($json, function($entry) { return $entry['availableForExchange']; });
echo 'Entries: '.count($found);
print_r($found);

By using array_column to access the availableForExchange values directly, you can use array_filter with no callback (since the values in that column are boolean):
$json = json_decode($data, true);
$available = count(array_filter(array_column($json, 'availableForExchange')));
echo "$available available for exchange\n";
Output (for your sample data)
0 available for exchange
Demo on 3v4l.org

Related

PHP-file_get_contents: Unable to check two file_get_contents in a single if statement

I am running two api calls through the same if statement to make sure they both return values. A form of error checking.
They both pass the test, however the first file_get_contents cannot be accessed or decoded by json_decode.
if (
$exchangeRates = (file_get_contents('https://api.coinbase.com/v2/exchange-rates'))
&&
$data = (file_get_contents('https://api.coinbase.com/v2/prices/spot?currency=USD'))
){
$json1 = json_decode($exchangeRates, true);
$json2 = json_decode($data, true);
return [$json1, $json2];
}
The above returns:
[
1,
{
"data":
{
"base": "BTC",
"currency": "USD",
"amount": "3532.335"
}
}
]
When I refer to individual values in $json1 they return null.
When the url's are entered into a url manually they both return the appropriate JSON.
Can only one file_get_contents be used per if statement?
Please check the Operator Precedence, && is on higher priority so it executes get_file_contents first, then use && and returns to $exchangeRates. Finally, $exchangeRates is the boolean. you should use () correctly in this case:
if (
($exchangeRates = file_get_contents('https://api.coinbase.com/v2/exchange-rates'))
&&
($data = file_get_contents('https://api.coinbase.com/v2/prices/spot?currency=USD'))
) {
$json1 = json_decode($exchangeRates, true);
$json2 = json_decode($data, true);
return [$json1, $json2];
}

Remove JSON array index that holds specific value with PHP

I am brand new to php.I have found questions that show how to remove key/value pairs from JSON files with php, but not array indexes.
I have worked out how to append values to arrays in a JSON file with json_decode(). But not how to remove values. I need to produce a function() that hunts for c and removes any value within an array in my JSON file. Below is a before and after of the expected outcome I need to produce with my php file.
// before
[["a", "c", "b"], ["c", "c"], [], ["c", "d"], ["d"], ["e"]]
// after
[["a", "b"], [], [], ["d"], ["d"], ["e"]]
Below is the function I have produced in order to add values to arrays in my JSON if this helps provide more context:
function appendClient($file, $post, $client) {
$a = fopen($file, "r");
$json = json_decode(fread($a, filesize($file)));
$json[$post][] = $client;
fclose($a);
$a = fopen($file, "w");
fwrite($a, json_encode($json));
fclose($a);
}
Use array_filter
function removeClient($file, $post, $client) {
$json = json_decode(file_get_contents($file));
$json[$post] = array_filter($json[$post], function($x) use($client) {
return $x != $client;
});
file_put_contents($file, json_encode($json));
}
This assumes all the elements of the array are either empty arrays or 1-element arrays containing the client name, as in the example you showed.
Take a look at array_filter and array_values functions.
[["a"],[],["b"],["c"]]
From the above input, I am assuming you are working with 2d array. Then, you can use the following function to do the job:
function removeValues($array, $value) {
$result = [];
foreach ($array as $row) {
$filtered = array_filter($row, function($entry) use($value) {
return $entry != $value;
});
// If you need to reset keys
$filtered = array_values($filtered);
$result[] = $filtered;
}
return $result;
}
Example:
$input = [["a"],[],["b"],["c"]];
$output = removeValues($input, "c");
print_r($output);

How to get top 5 higher values in json files inside folder

public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$levels = $json["level"];
}
}
I want to get top 5 higher values from all json files in "players" folder, I only know how to get that value from all files, but don't know how to select 5 higher. Can someone help please?
EDIT: Json file looks like this:
{
"coins": 0,
"rank": "Guest",
"accept_friends": true,
"reward_time": 1440,
"level": "29",
"bio": "Today is very cool!c",
"progress": 24.939999999999998,
"local_ip": "10.0.0.1",
"registred": true,
"logged": true
}
Use usort!
Make a function that will handle your sorting:
function levelSort($a, $b)
{
return $a['level']>$b['level'];
}
next store your players to array, sort it and return first five elements:
public function onRun(int $currentTick){
$players = []; // declare aray with proper scope
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$players[] = $json; // save to array
}
usort($players, 'levelSort'); // sort using custom function
return array_slice($players, 0, 5); // return 5 elements
}
Should work. didn't tested tho :D
Of course this example assuming that every $json is an array and $json['level'] exists and is int
You need to build an array of levels with $levels[] as you are overwriting $levels each time. Then just reverse sort and slice the top 5:
public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$levels[] = $json["level"];
}
rsort($levels);
return array_slice($levels, 0, 5);
}
If you want to return the entire top 5 arrays:
public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$results[] = json_decode($str, true);
}
array_multisort(array_column($results, 'level'), SORT_DESC, $results);
return array_slice($results, 0, 5);
}
Why are you passing in an argument $currentTick and not using it? Maybe replace 5 with $currentTick so you can pass it in?

Using serialized data from AJAX object with PHP

I'm sending an entire form, about 8 fields, along with my AJAX data object, one of which is a serialized string:
var fields = $(this).serialize();
var data = {
action:'newSubmission',
nonce: Nonce,
fields: fields
};
Now within PHP I cannot understand how to get each field value from the $_POST object correctly.
$test = $_POST['field'];
Is the full string and sends back to JS a properly formatted JSON object. But how do I break up the serialized string correctly in PHP?
The string will be encoded, so you will have to do that with url_decode.
Here is a function that I used to build a workable object out of the string.
function urldecode_to_obj($str) {
$str = trim($str, '"');
// explode string before decoding
foreach (explode('&', $str) as $chunk) {
$param = explode("=", $chunk);
if ($param) {
// search string for array elements and look for key-name if exists
preg_match('#\[(.+?)\]$#', urldecode($param[0]), $with_key);
preg_match('#\[\]$#', urldecode($param[0]), $no_key);
$mkey = preg_split('/\[/', urldecode($param[0]));
// converts to array elements with numeric key
if ($no_key) {
$data[$mkey[0]][] = urldecode($param[1]);
}
// converts to array elements with named key
if ($with_key) {
$data[$mkey[0]][$with_key[1]] = urldecode($param[1]);
}
if (!$no_key && !$with_key) {
$data[urldecode($param[0])] = urldecode($param[1]);
}
}
}
return (object)$data;
}
$str = "serialized_string";
$obj = urldecode_to_obj($str);
Your variables with values are now in the object. If you have a var1 variable in there with a value1:
$obj -> var1 = "value1";
You can also get thins back as an array. Just omit the (object) casting and return the data in t\he function as:
return $data;
If you want to return things to your JS then you should echo them out as an array and use json_encode:
$array = array("success" => true);
echo json_encode($array);
Try using:
$serializedData = file_get_contents("php://input");
$unserializedData = array();
parse_str($unserializedData,$serializedData);
print_r($unserializedData);
instead of the PHP $_POST superglobal use the php://input.
PHP "php://input" vs $_POST
Then you can use theparse_str() php function to turn the serialized string into a php array.
There are also a number of other ways to manually do this if you so choose:
function unserializeForm($str) {
$returndata = array();
$strArray = explode("&", $str);
$i = 0;
foreach ($strArray as $item) {
$array = explode("=", $item);
$returndata[$array[0]] = $array[1];
}
return $returndata;
}

Delete from json using php

my Current json code :
{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}
i want to remove this :
{"username":"google","password":"test"}
from the code using php.
i tried deleting by decoding json to array but cant get it done.
any solution ?
$json_obj = json_decode($json_string);
$unset_queue = array();
foreach ( $json_obj->Results as $i => $item )
{
if ($item->username == "google")
{
$unset_queue[] = $i;
}
}
foreach ( $unset_queue as $index )
{
unset($json_obj->Results[$index]);
}
// rebase the array
$json_obj->Results = array_values($json_obj->Results);
$new_json_string = json_encode($json_obj);
<?php
$JSON = '{"Results":['
. '{"username":"test","password":"test"},'
. '{"username":"test","password":"test"},'
. '{"username":"google","password":"test"},'
. '{"username":"yahoo","password":"test"},'
. '{"username":"hotmail","password":"test"}'
. ']}';
// use json_decode to parse the JSON data in to a PHP object
$jsonInPHP = json_decode($JSON);
// now iterate over the results and remove the one that's google
$results = count($jsonInPHP->Results);
for ($r = 0; $r < $results; $r++){
// look for the entry we are trying to find
if ($jsonInPHP->Results[$r]->username == 'google'
&& $jsonInPHP->Results[$r]->password == 'test'){
// remove the match
unset($jsonInPHP->Results[$r]);
// now we can either break out of the loop (only remove first match)
// or you can use subtract one from $r ($r--;) and keep going and
// find all possible matches--your decision.
break;
}
}
// now that we removed items the keys will be off. let's re-order the keys
// so they're back in-line
$jsonInPHP->Results = array_values($jsonInPHP->Results);
// dump the new JSON data, less google's entry
echo json_encode($jsonInPHP);
Would be how I approach it. I like to avoid foreach(...){} statements when I need to modify the array itself. The above code, by the way, leaves you with:
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}
$json = '
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"google","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}';
$arr = json_decode($json, true);
array_filter($arr, function($v) {
return !($v['username'] == 'google' && $v['password'] == 'test');
});
$json = json_encode($arr);
$input='{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}';
$json = json_decode($input,true);
$match = array('username'=>'google', 'password'=>'test');
unset($json['Results'][array_search($match,$json['Results'])]);
To do it without a foreach but assuming you know the exact values you want to remove
Old question, formatting your JSON differently would help a lot.
Each result entry should have a unique key to identify it.
This makes it easy when needing to remove or update that result.
No reason to iterate over entire JSON this way.
Code would look like this
<?php
$jsonString = '{"Results":{'
.'{"username1":{"username":"google","password":"test1"}}'
.'{"username2":{"username":"yahoo","password":"test2"}}'
.'{"username3":{"username":"msonline","password":"test3"}}'
. '}}';
$jsonInPHP = json_decode($jsonString);
$password = $jsonInPHP["username1"]["pasword"];//Returns test1
$username = $jsonInPHP["username1"]["username"];//Returns google
?>
$myArray=json_decode($theJSONstring);
unset($myArray['Results'][2]);

Categories