Delete JSON item inside an sub-array - php

I wonder how can I unset the target array whenever i wanted in PHP. It's a product list and the procedure im planning if i want to delete a products. Here's the JSON structure
{
"Merchant": "SAMHONEY",
"date": 1632482493,
"archive": "true",
"extra": "Byahe",
"data": [
{
"product-image": "https:\/\/mobi.asia\/assets\/abunjing-stand.png",
"name": "Sample Product",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "26"
},
{
"product-image": "https:\/\/mob.asia\/assets\/abunjing-stand.png",
"name": "Sample Product 2",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "99"
},
{
"product-image": "https:\/\/mob.asia\/01162020\/images\/storage\/1632200295.png",
"name": "Product C",
"des": "Great coffee",
"price": "3"
},
{
"product-image": "https:\/\/mob.asia\/01162020\/images\/storage\/1632200342.png",
"name": "Product A",
"des": "Caramel Coffee",
"price": "4"
}
]
}
What I done in PHP is this
$pos = $_POST['position'];
$jsn = file_get_contents('../datamer/archives/'.$sbd.".json");
$arr = json_decode($jsn, true);
$acc = $arr["data"];
unset($acc[$pos]);
$arr["data"] =$acc;
file_put_contents('../datamer/archives/'.$sbd.".json",json_encode($arr,JSON_PRETTY_PRINT));
And the output is it was re-structuring the JSON into this.Which not im expecting
{
"Merchant": "SAMHONEY",
"date": 1632482493,
"archive": "true",
"extra": "Byahe",
"data": {
"0": {
"product-image": "https:\/\/mobile.byahe.asia\/assets\/abunjing-stand.png",
"name": "Sample Product",
"des": "Byahe Palawan Merchant Dashboard v.1.1",
"price": "26"
},
"2": {
"product-image": "https:\/\/mobile.byahe.asia\/01162020\/images\/storage\/1632200295.png",
"name": "Product C",
"des": "Great coffee",
"price": "3"
},
"3": {
"product-image": "https:\/\/mobile.byahe.asia\/01162020\/images\/storage\/1632200342.png",
"name": "Product A",
"des": "Caramel Coffee",
"price": "4"
}
}
}
Kindly enlighten me to this. I'm still learning,. Thanks in advance for the attention. Well appreciated.

Related

Array filter JSON data with price parameter

I have this JSON data and I am using this code to match the title. It works, but now I want to go one step further and list all products which are less than some price, or more than some price, or equal to some price
$json = '[{
"id": 2042049298481,
"title": "Test Product 53",
"variants": [{
"id": 15733087797297,
"title": "Default Title",
"price": "100.00",
"sku": "no"
}]
}, {
"id": 2196682342449,
"title": "its test yar",
"variants": [{
"id": 16385289879601,
"title": "Default Title",
"price": "144.00",
"sku": "no"
}]
}, {
"id": 4175970041905,
"title": "uhjkjhkhk",
"variants": [{
"id": 30302326554673,
"title": "Default Title",
"price": "1000.00",
"sku": "10"
}]
}, {
"id": 4183828791345,
"title": "kaminsss",
"variants": [{
"id": 30346449518641,
"title": "Default Title",
"price": "111.00",
"sku": "no"
}]
}, {
"id": 4247884890161,
"title": "hellooo",
"variants": [{
"id": 30579860832305,
"title": "Default Title",
"price": "1111.00",
"sku": "no"
}]
}, {
"id": 4248143822897,
"title": "10oct latest collection",
"variants": [{
"id": 31157780938801,
"title": "50",
"price": "111.00",
"sku": "no-1"
}, {
"id": 31157802270769,
"title": "60",
"price": "101.00",
"sku": ""
}, {
"id": 31157804761137,
"title": "70",
"price": "111.00",
"sku": ""
}]
}, {
"id": 4284600746033,
"title": "18oct2019",
"variants": [{
"id": 31595410030641,
"title": "120 / black",
"price": "100.00",
"sku": "10"
}]
}, {
"id": 4285596860465,
"title": "test2222",
"variants": [{
"id": 30877916921905,
"title": "Default Title",
"price": "111.00",
"sku": "no"
}]
}]';
$array = json_decode($json,1);
$filter_name ='title';
$filter_value ='Test';
$expected88 = array_filter($array, function($el) use ($filter_value, $filter_name) {
return ($el[$filter_name] >= $filter_value);
});
echo json_encode($expected88,true);
This works flawlessly for title but we want to filter based on variant price. There may be several prices for one variant and if $filter_value is greater than, equal to, or less than, anyone can occur.
For example user may search for product whose minimum price is 50, so in that case, if any variant is matching criteria then it will list those products, or user may search that all variants' prices should be less than 50.
We tried like this
$expected = array_filter($array, function ($var) use ($filter_value) {
return ($var[$filter_name] >= $filter_value);
});
but it did not work.
We tried foreach and tested again but it always gave empty result
Here is possible solution
$filter_name ='variants';
$filter_value = 200;
$filter_field = "price";
$expected88 = array_filter($array, function($el) use ($filter_value, $filter_name, $filter_field) {
return ((int)$el[$filter_name][0][$filter_field] >= (int)$filter_value);
});

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

PHP | How to define large empty multidimensional array/object

I am trying to store the user's response for a detailed fitness report questionnaire in MongoDB. Once the form is submitted I would parse the form data and create an array/object which has a predefined structure.
I was thinking of creating a class with the whole object hierarchy with values set to empty string ''. The response I want to store looks like this:
{
"_basic": {
"_response_type": "text",
"_response": {
"name": "eNeMetchH",
"gender": "male",
"age": 20,
"contact": "9876543210",
"email": "email#email.com",
"dob": "1997-03-20",
"package": {
"id": "1001",
"name": "Alpha Monthly",
"start_date": "2017-01-01",
"end_date": "2017-01-31"
}
}
},
"_parq": {
"footnotes": "If yes to one or more questions, please talk to your doctor before you start becoming more physically active or before you have a fitness appraisal. Tell your doctor about the PAR-Q and which questions you have answered yes.",
"response_type": "radio",
"response": [
{
"question": "Has your doctor ever said you have a heart condition and you should only do physical activity that is described by doctor?",
"response": "NO"
},
{
"question": "Do you feel pain in your chest when you do physical activity?",
"response": "NO"
},
{
"question": "In the past month, have you had chest pain when you were not doing physical activity?",
"response": "NO"
},
{
"question": "Do you lose your balance because of dizziness or do you ever lose consciousness?",
"response": "NO"
},
{
"question": "Do you have a bone or joint problem that could not be made worse by a change in your physical activity?",
"response": "NO"
},
{
"question": "Is your doctor currently prescribing drugs for your BP & Heart conditions?",
"response": "NO"
},
{
"question": "Do you know any other reason why you should not do physical activity?",
"response": "NO"
}
]
},
"_conditioning_level": "_intermediate_1_3",
"_occupation": "_professional",
"_primary_goal": "_weight_gain",
"_secondary_goal": "_muscular_strength",
"_workout_intensity": "_mild",
"_availability": {
"_days_per_week": "6",
"_min_per_day": "90"
},
"_sleep": "_insomnia",
"_physical_activity": "_sedentary",
"_stress_level": "_mild",
"_medical_history": [
"_knee_pain",
"_hypertension",
"_high_cholesterol"
],
"_alcohol": "_alcoholic",
"_smoking": "YES",
"_tobacco": "NO",
"_shoe_analysis": {
"_toe_box": "_normal",
"_torsion": "_normal",
"_heel_support": "_abnormal",
"_arch": "_normal"
},
"_postural_analysis": {
"_head_neck": "Blah blah",
"_shoulder": "Blah blah",
"_thoracic_spine": "Blah blah",
"_lumbar_spine": "Blah blah",
"_knee": "Blah blah",
"_feet": "Blah blah"
},
"_anthropometry": {
"_bp": "160/90 mm/Hg",
"_resting_heart_rate": "90 bpm",
"_weight": "82",
"_height": "183",
"_bmi": "20"
},
"_functional_movement": {
"_ssn": "Blah blah",
"_height": "183",
"_weight": "82",
"_primary_score": "Dono",
"_primary_position": "Dono",
"_hand_leg_dominance": "Dono",
"_previous_test_score": "Dono",
"tests": {
"_deep_squat": [
{
"_raw_score": "30",
"_final_score": "40"
}
],
"_hurdle_step": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_inline_lunge": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_shoulder_mobility": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_impingement_clearing_test": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_active_straight_leg_raise": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_trunk_push_up": [
{
"_raw_score": "30",
"_final_score": "40"
}
],
"_press_up_test": [
{
"_raw_score": "30",
"_final_score": "40"
}
],
"_rotary_stability": {
"L": {
"_raw_score": "30",
"_final_score": "40"
},
"R": {
"_raw_score": "30",
"_final_score": "40"
}
},
"_posterior_rocking_test": [
{
"_raw_score": "30",
"_final_score": "40"
}
],
"_total": [
{
"_raw_score": "30",
"_final_score": "40"
}
]
}
},
"_fitness_test": {
"_aerobic_endurance": {
"_distance_covered": "2 km",
"_pre_heart_rate": "72",
"_post_heart_rate": "95",
"_vo2_max": "90",
"_mets": "30"
},
"_muscular_strength": {
"_upper_body": "6",
"_lower_body": "7"
},
"_muscular_endurance": {
"_ab_crunches": "6",
"_free_squats": "7"
},
"_flexibility": {
"_sit_reach": "5",
"_cobra_stretch": "6"
},
"_proprioception": {
"_lt_side": "10",
"_rt_side": "10"
},
"_core_strength": {
"_iron_man": "55"
}
},
"_assessment_summary": {
"_age": "20",
"_sex": "_male",
"_conditioning_level": "_intermediate_1_3",
"_goal": "_weight_gain",
"_occupation": "_professional",
"_stress_level": "_mild",
"_health_problem": "None",
"_test_result": "Need fat loss and Increment in lung capacity",
"_preferences": "None whatsoever"
},
"_remarks": "Blah blah blah"
}
I need to create a template with the above structure intact and empty values. Adding anymore keys or removing keys should not be allowed.
What is the best approach for this?
If you keep the variable as protected, then it can be modified only by member functions and cannot be accessed directly. The __set function will prevent addition of new variable.
create a class
class Foo{
// if you keep the variable as protected, then it can be modified only
// by member functions so noone will be able to remove the variable.
protected $v1;
// this set function will prevent addition of new variable.
public function __set($name, $value) {
throw new Exception("Cannot add new property \$$name to instance of " . __CLASS__);
}
}
Example for a property such as occupation, you have to define it as
protected $occupation = "professional";

Display some parts of a file written in json

Below is my JSON file:
{
"example": "1",
"example2": 2,
"text": "3",
"info": {
"agent": 4,
"sum": 5,
"collection": [{
"Name": "6",
"Pic": "7"
} {
"Name": "8",
"Pic": "9"
}, {
"Name": "10",
"Pic": "11"
}]
}
}
How would I display each 'name' and 'pic' I think I need to use a foreach loop but don't know how to.
This is all the code I have:
$data = json_decode(file_get_contents('http://linktojson.com'));
echo $data['info']['collection'][0]['Name'];
echo $data['info']['collection'][0]['Pic'];
This should work
$data = json_decode(file_get_contents('http://linktojson.com'));
echo "<pre>".print_r($data,1)."</pre>";
foreach($data->info->collection as $key){
echo $key->Pic;
echo $key->Name;
}
Valid JSON
{
"example": "1",
"example2": 2,
"text": "3",
"info": {
"agent": 4,
"sum": 5,
"collection": [{
"Name": "6",
"Pic": "7"
}, {
"Name": "8",
"Pic": "9"
}, {
"Name": "10",
"Pic": "11"
}]
}
}

remove unnecessary hierarchy from json output

I am building an admin backend for an android app. My code provides a json output which the android developer then uses in his app. The developer asked me if it is possible to reduce the hierarchy level in the json output
as in remove the highlighted []0 and put the contents directly inside the []data instead.
This is my current php code
if($type == 1 ) //Handle item display
{
try
{
$query = "SELECT category FROM category";
$result= $DBH->query($query);
while($row = $result->fetch(PDO::FETCH_ASSOC))
{
$cat = $row['category'];
$query1 = "SELECT * FROM item WHERE catagory='$cat'";
$value = $DBH->query($query1);
if($row1 = $value->fetchAll(PDO::FETCH_OBJ)){
$main[] = array('data'=>array($row1));
}
else
{
$main[] = array('data'=>array('catagory'=>$row['category']));
}
}
echo json_encode($main);
$result->closeCursor(); //Close database connection free resources
$DBH = null;
}
catch(PDOException $e){
print $e->getMessage ();
die();
}
}
And the json output being generated
[
{
"data": [
[
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
]
},
{
"data": {
"catagory": "Dinner"
}
},
{
"data": {
"catagory": "Soup"
}
},
{
"data": {
"catagory": "Test"
}
}
]
I am not very sure if I can make the changes he asked or if it is possible. Is it doable?
Your json structure is inconsistent and try this approach, will be easier for the developer to parse
{
"response": [
{
"data": [
{
"id": "2",
"name": "rice",
"price": "20",
"description": "Plain Rice",
"image": "4106_rice.jpg",
"time": "12 mins",
"catagory": "Lunch",
"subcat": ""
},
{
"id": "3",
"name": "item 1",
"price": "32",
"description": "item 1 description",
"image": "1370_2Ckjikljklkljh.jpg",
"time": "10",
"catagory": "Lunch",
"subcat": "Chicken Soup"
},
{
"id": "4",
"name": "hello",
"price": "10",
"description": "fgsdjfsfsdj",
"image": "",
"time": "76",
"catagory": "Lunch",
"subcat": ""
}
]
},
{
"data": [
{
"catagory": "Dinner"
}
]
},
{
"data": [
{
"catagory": "Soup"
}
]
},
{
"data": [
{
"catagory": "Test"
}
]
}
]
}

Categories