How to not loop through an object - php

I have an object that looks like this
{
"Product_1": {
"name": "Product 1",
"price": "300"
},
"Product_2": {
"name": "Product 2",
"price": "300"
},
"Product_3": {
"name": "Product 3",
"price": "300"
},
}
What I would like to know is. Is it possible to grab the keys for example: Product_1, Product_2 without having to loop through it?

Yes you can using the array_keys method like this:
$json = '{
"Product_1": {
"name": "Product 1",
"price": "300"
},
"Product_2": {
"name": "Product 2",
"price": "300"
},
"Product_3": {
"name": "Product 3",
"price": "300"
}
}';
$array = json_decode($json, JSON_OBJECT_AS_ARRAY);
$keys = array_keys($array);

You can get all keys of the object simply by call the function get_object_vars()

Related

Changing a string in a json object

I'm trying to update a json file and I'm using laravel command to do it. In that file there are specific product codes that need to be changed. The code I'm doing to do this isn't working, it runs but nothing changes.
Here is my code
$old_code = 'P001';
$new_code = 'P011';
$productJson = json_decode(file_get_contents(storage_path('/Product 1/product.json')));
foreach($productJson as $key => $value){
str_replace($old_code, $new_code, $k);
}
file_put_contents(storage_path('/Product 1/product.json), json_encode($productJson, JSON_PRETTY_PRINT));
and this is my json file
{
"P001": {
"name": "Product 1",
"price": "200",
"category": "Shirts"
},
"P002": {
"name": "Product Test",
"price": "100",
"category": "Tops"
},
}
Its probably simpler to read the file and create a new JSON with the new codes like this
$s = '{"P001": {
"name": "Product 1",
"price": "200",
"category": "Shirts"
},
"P002": {
"name": "Product Test",
"price": "100",
"category": "Tops"
},
"P003": {
"name": "Product Test",
"price": "50",
"category": "Bottoms"
}
}';
$old_codes = ['P001', 'P002' ];
$new_codes = ['P011', 'P022' ];
$productJson = json_decode($s);
$new = new stdClass;
foreach($productJson as $key => $json){
$kk = array_search($key, $old_codes);
if ( FALSE !== $kk ) { // found
$new->{$new_codes[$kk]} = $json;
} else {
$new->{$key} = $json;
}
}
echo json_encode($new, JSON_PRETTY_PRINT);
//file_put_contents(storage_path('/Product 1/product.json'), json_encode($new, JSON_PRETTY_PRINT));
RESULT
{
"P011": {
"name": "Product 1",
"price": "200",
"category": "Shirts"
},
"P022": {
"name": "Product Test",
"price": "100",
"category": "Tops"
},
"P003": {
"name": "Product Test",
"price": "50",
"category": "Bottoms"
}
}

How to loop through an array without repeating?

I'm trying to get data from API and I receive this
[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]
I want to get the category for each service without repeating the same category twice.
Edited*
I have this code
$servers = $this->Setting->Loop('api','WHERE is_active = 1');
foreach($servers->result() as $server){
foreach($this->Api_Connect->services($server->api_url, $server->api_key) as $item) {
echo '<option data-server='.$server->id.' data-percent='.$server->addon_percent.' data-price='.$item['rate'].' data-min='.$item['min'].' data-max='.$item['max'].' value="'.$item['service'].'">- '.$item['name'].'</option>';
}
}
which connect to each server with api url and key and return with the services.
We can set a new array, and push categories in the new array, and check if the new value does not exist do so:
$data = '[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$data = json_decode($data, true);
$category = array();
foreach ($data as $value) {
if (!array_search($value["category"], $category)) {
array_push($category, $value["category"]);
}
}
var_dump($category);
Output
array(2) {
[0]=>
string(14) "First Category"
[1]=>
string(15) "Second Category"
}
Edit:
Based on Andreas's advice, we can also use if(in_array()) in the loop using:
$category[$value["category"]] = $value["category"];
which is much more efficient.
$array = [];
foreach($object as $key => $value) {
// object is data you receive from API
array_push($array,$value->category);
}
// to get unique values
$array = array_unique($array);
I hope this code solve your problem
The fastest method is to use array_column.
Array_column will isolate one column of the array.
The third parameter of array_column will set the key name.
This is what we want.
Because you don't want duplicates we set something as value and "category" as key.
This means it will loop once and overwrite the keys that is duplicated.
The other methods posted here will need to check if the item is already added to the list or using array_unique which needs to compare each item with every other item, that is a slow function when you give it a large array.
$data = '[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$data = json_decode($data, true);
$category = array_column($data, "rate", "category");
var_dump($category);
Output of this:
// Note it's only the keys we want, the values are not interesting
array(2) {
["First Category"]=>
string(4) "0.90"
["Second Category"]=>
string(1) "8"
}
$jsonResponse='[
{
"service": 1,
"name": "Followers",
"type": "Default",
"category": "First Category",
"rate": "0.90",
"min": "50",
"max": "10000"
},
{
"service": 2,
"name": "Comments",
"type": "Custom Comments",
"category": "Second Category",
"rate": "8",
"min": "10",
"max": "1500"
}
]';
$listData=json_decode(jsonResponse,true);
foreach($listData as $valRes){
echo $valRes['category'];
}
you can get category

Rewrite json in loop

I have an array, which i wrote like a table for more reability.
[{
"id": "1",
"title": "boune",
"value": "3"
}, {
"id": "2",
"title": "check",
"value": "4"
}, {
"id": "3",
"title": "boune",
"value": "5"
}]
As the result of what i want to see is this json, where 'value' of identical 'titles' united inside [] brackets. I am very newbie in php. I undestand that i need for loop to sort query result, but can`t heck...Cant even put my mind to it...
[{
"id":"1",
"title": "boune",
"value": [3, 5]
}]
<?php
$json = '[{"id":"1","title":"boune","value":"3"},{"id":"2","title":"check","value":"4"},{"id":"3","title":"boune","value":"5"}]';
$json_data = json_decode($json,true);
function accumulateValuesByTitle($json_data){
$hash = [];
foreach($json_data as $each_record){
if(isset($hash[$each_record['title']])){
$hash[$each_record['title']]['value'][] = $each_record['value'];
if($hash[$each_record['title']]['id'] > $each_record['id']){
$hash[$each_record['title']]['id'] = $each_record['id'];
}
}else{
$hash[$each_record['title']] = $each_record;
$hash[$each_record['title']]['value'] = [$hash[$each_record['title']]['value']];
}
}
return array_values($hash);
}
$modified_data = accumulateValuesByTitle($json_data);
echo json_encode($modified_data);

Simplifying my JSON to build a array.

I am trying to take my JSON input and generate a easy array to search in, but it is as far as I can tell giving me some trouble.
First of, this is my JSON as is, loaded from a file:
{
"teams": [
{
"id": "1",
"boat": "Test",
"name": "Palle Test"
},
{
"id": "2",
"boat": "Test 2",
"name": "Name Test 2"
},
{
"id": "3",
"boat": "Test 3",
"name": "Name Test 3"
},
{
"id": "4",
"boat": "Test 4",
"name": "mller"
}
]
}
Is there a way to simplify this or minimise the number of arrays?
I have been using the following code to preview my array, but I am trying to get it to search for id and then print the values for id, boat and name.
$json_url = "teams.json";
$json = file_get_contents($json_url);
$data = json_decode($json, TRUE);
echo '<pre>';
print_r($data);
echo '</pre>';
This is really quite simple. There is no need to convert a perfectly good object into an array, it only makes life more complex.
The only array you have in your data structure is the teams array and that is easily processed like this
$json = '{
"teams": [
{
"id": "1",
"boat": "Test",
"name": "Palle Test"
},
{
"id": "2",
"boat": "Test 2",
"name": "Name Test 2"
},
{
"id": "3",
"boat": "Test 3",
"name": "Name Test 3"
},
{
"id": "4",
"boat": "Test 4",
"name": "mller"
}
]
}';
$data = json_decode($json);
//print_r($data);
foreach ($data->teams as $object) {
if ( $object->id == 2) {
echo 'boat is ' . $object->boat . ' and name is ' . $object->name . PHP_EOL;
}
}
And the result of the above example would be
boat is Test 2 and name is Name Test 2

Add field to a JSON file

I have a very simple JSON file "json.txt" :
{
"status": true,
"data":
{
"clics":
[
{
"id": "1",
"title": "Title 1",
"comment": "Blablabla 1",
"url": "http://photostodisplay/1.jpg"
},
{
"id": "2",
"Title": "Title 2",
"comment": "Blablabla 2",
"url": "http://photostodisplay/2.jpg"
}
]
}
}
and I would like to add data and get the following result :
{
"status": true,
"data":
{
"clics":
[
{
"id": "1",
"title": "Title 1",
"comment": "Blablabla 1",
"url": "http://photostodisplay/1.jpg"
},
{
"id": "2",
"Title": "Title 2",
"comment": "Blablabla 2",
"url": "http://photostodisplay/2.jpg"
},
{
"id": "3",
"Title": "Title 3",
"comment": "Blablabla 3",
"url": "http://photostodisplay/3.jpg"
}
]
}
}
The php code I use return the following error :
Fatal error: Cannot use object of type stdClass as array in /home/XXXX/www/clic/test.php on line 10
Here is the php code
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
$file = 'json.txt';
$data = json_decode(file_get_contents($file));
$newdata = array('id'=>'11', 'title' => 'sfdfsdfqf', 'comment' => 'sfdfwwfwdsdfqf', 'url' => 'sdfqwsfsdqqfqqqsfcq');
$data[] = $newdata;
file_put_contents($file, json_encode($data));
echo OK
?>
EDIT - Cezary answer gives almost what I need but is not. Here is what I get :
{
"status": true,
"data": {
"clics": [
{
"id": "1",
"title": "Title 1",
"comment": "Blablabla 1",
"url": "http://photostodisplay/1.jpg"
},
{
"id": "2",
"Title": "Title 2",
"comment": "Blablabla 2",
"url": "http://photostodisplay/2.jpg"
}
]
},
"0": {
"id": "11",
"title": "sfdfsdfqf",
"comment": "sfdfwwfwdsdfqf",
"url": "sdfqwsfsdqqfqqqsfcq"
}
}
The issue lies with this bit of code:
$data = json_decode(file_get_contents($file));
This returns an object, not an associative array. Change that line to this:
$data = json_decode(file_get_contents($file), true);
The second argument in json_decode specifies whether you want an associative array or not, and it defaults to false.
EDIT:
You're currently adding something to the root array. To add to the clics array, you can replace $data[] = $newdata; with:
$data['data']['clics'][] = $newdata;
Shouldn't that be
$data["data"]["clics"][]=$newdata;
or
array_push($data["data"]["clics"],$newdata);

Categories