Removing a JSON record from .json file with PHP - php

I have a json file looking like this :
[["{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}"],["{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}"],["{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}"]]
What I am trying to do is to remove a record from it by it's id. For this purpose I have the following PHP code :
<?php
$string = file_get_contents("products.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= $_GET['data'];
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
var_dump($arr);
$arr2 = array();
foreach ($arr as $key) {//trying to make it look like the original json.
array_push($arr2,json_decode($key[0],true));
}
//var_dump($arr2);
echo json_encode($arr2);
?>
What I am getting from this code is :
array(2) { [0]=> array(4) { ["id"]=> float(1474721566304) ["name"]=> string(3) "GGG" ["brand"]=> string(2) "GG" ["price"]=> string(1) "3" } [1]=> array(4) { ["id"]=> float(1474721570904) ["name"]=> string(4) "GGGH" ["brand"]=> string(3) "GGH" ["price"]=> string(1) "4" } }
I am really out of ideas how to make this array look like my original JSON shown first on this post. I tried many different things, but I couldn't make it work. My idea is after removing the record by it's ID to replace the old JSON with the new one that I am trying to construct here.
I am new to php and I'd appreciate any input on my issue.

First of all - your input JSON is wrong:
array (size=3)
0 =>
array (size=1)
0 => string '{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}' (length=58)
1 =>
array (size=1)
0 => string '{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}' (length=60)
2 =>
array (size=1)
0 => string '{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}' (length=61)
You don't have 'id' nor 'name', 'GGG' and other keys. You just have one long string. You should remove unnecessary quotation marks. After that your JSON should look like this:
[[{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}],[{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}],[{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}]]
And finally, your PHP code can be much shorter:
$json = "[[{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}],[{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}],[{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}]]";
$input = json_decode($json, true);
$output = array();
foreach($input as $element) { //you don't need to declare yet another array, just use the one you already have
if($_GET['data'] != $element[0]["id"]){ //and not unset, just add to new array if you want
$output[] = $element; //shorter and faster than array_push()
}
}
echo json_encode($output);

Try this code:
$string = file_get_contents("product.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= 0;
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
// print_r($arr);
$arr2 = array();
foreach($arr as $key => $val) {
$arr2[][] = $val;
}
//var_dump($arr2);
echo json_encode($arr2);

Related

PHP Str_replace is not working in foreach loop

Here is my code.
I am trying to get inspect link for steam item. I have tried to use preg_replace but no luck either.
$API_link = sprintf("http://steamcommunity.com/id/*steamid*/inventory/json/730/2?trading=1");
$json = file_get_contents($API_link);
$json_output = json_decode($json);
$result = $json_output;
$link = array();
$id = array();
foreach($result->rgDescriptions AS $item){
$empty = array();
$newstring = $item->actions[0]->link;
if($newstring == NULL){
continue;
} else {
$empty['link'] = $newstring;
array_push($link, $empty);
}
}
foreach($result->rgInventory AS $inventory){
$empty = array();
if($inventory->instanceid == 0){
continue;
} else {
$empty['id'] = $inventory->id;
array_push($id, $empty);
}
}
$array = array_merge($id, $link);
foreach($array AS $final){
$assetid = "%assetid%";
echo str_replace($assetid, $final['id'], $final['link']);
}
}
But its not working. Please see if you can help.
As I can see you have array of arrays:
// bracket squares equivalent of array() keyword PHP >=v5.4
// here is
// $link = array(['link'=>'url'],['link'=>'url'])
// $id = array(['id'=>'id'],['id'=>'id'])
// result will be:
// array(['link']=>'url'],['link'=>'url'],['id'=>'id'],['id'=>'id'])
$array = array_merge($id, $link);
foreach($array AS $final){
// here is the first $final
// array('link'=>'url')
$assetid = "%assetid%";
// but here is we try to get
// 'id' and 'link'
echo str_replace($assetid, $final['id'], $final['link']);
}
I think it's some kind of mistake.
Ok, some test script:
<?php
$a = array( array('link'=>'hello1'), array('link'=>'hello2'));
$b = array( array('id'=>'id0'), array('id'=>'id1'));
$c = array_merge($a, $b);
var_dump($c);
result:
array(4) {
[0] =>
array(1) {
'link' =>
string(6) "hello1"
}
[1] =>
array(1) {
'link' =>
string(6) "hello2"
}
[2] =>
array(1) {
'id' =>
string(3) "id0"
}
[3] =>
array(1) {
'id' =>
string(3) "id1"
}
}
array_merge doesn't mix your associative arrays between them nether all nor particular item (I hope I explain it correct)
of course
foreach ($c as $item) {
var_dump($item);
}
will enumerate all the items one by one
array(1) {
'link' =>
string(6) "hello1"
}
array(1) {
'link' =>
string(6) "hello2"
}
array(1) {
'id' =>
string(3) "id0"
}
array(1) {
'id' =>
string(3) "id1"
}
and there is no array that has both of them (link and id) in the item
This script can't associate link and id properly, cause some of links can be skipped by continue, some of id also can be skipped. And it will be just a random list of available information. You can stuck in the next situation:
- $links has first 10 links
- $id has 3,4,5,7,9,11
It's just a list. Even if you have only this pure info (no other details), you can't properly associate it between of them by using shown source.
Here is minimum 1 simple solutions:
don't skip, don't merge, just add an empty array, and your final loop will be like this:
$assetid = "%assetid%";
for ($link as $key=>$final) {
if (count($final) && count($id[$key])) {
echo str_replace($assetid, $id[$key]['id'], $final['link']);
} else {
// some of needed arguments absent
}
}
Description not enough. Maybe try dump some variables?
foreach($array AS $final){
$assetid = "%assetid%";
//Check what is in $final
var_dump($final);
echo str_replace($assetid, $final['id'], $final['link']);
}

How to delete elements from array from certain value on?

I have an array in PHP and I don't know how to delete all the elements from every array element from certain character on, icluding that character. Is there a way to do this?
array(1092) {
["Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite"]=>
int(124)
}
In my example I want to delete all text from "#####", including "#####" to the end, foreach array element. Is this possible? Or is there a PHP function for this?
UPDATE
My result should look like this:
array(1092) {
["Piper;Rosii;Sare;Test;Vinete]=>
int(124)
}
You can use array_walk to apply the substr and strpos to each element:
$array = [
'23845637;54634;345;3453345;#####morestuff',
'234234#####34596078345j34534534',
'34343245dfg#####asdfsadf;23452345;sdfsdf;345345'
];
array_walk($array, function(&$value, $key) {
$value = substr($value, 0, strpos($value, '#####'));
});
var_dump($array);
Will result in:
array(3) {
[0]=>
string(27) "23845637;54634;345;3453345;"
[1]=>
string(6) "234234"
[2]=>
string(11) "34343245dfg"
}
This will modify the original array.
For each element in the array, we search for the position of '#####' in the string and only take the part from 0 to the position in the string where '#####' occurs.
This will do that by looping through the array exploding the key by ##### and adding it to a new array. I did it in a loop in case your array is bigger than 1
<?php
$oldArray = array("Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124);
$newArray = array();
foreach ($oldArray as $key => $row) {
$newKey = explode('#####', $key);
$newArray[$newKey[0]] = $row;
}
var_dump($newArray);
You can use substr and strpos to add the new entry and then unset the old entry in the array like this example:
$array = array(
"Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124
);
foreach ($array as $key => $value) {
$array[substr($key, 0, strpos($key, '#####'))] = $value;
unset($array[$key]);
}
var_dump($array);
Will result in:
array(1) {
["Piper;Rosii;Sare;Test;Vinete"]=>
int(124)
}

Changes to array of JSON objects based on other array

I have an array of JSON objects that look like this:
{"id":1,"place":2,"pic_name":"aaa.jpg"}
My PHP file receives a simple array like:
["4","3","1","2","5"]
These numbers correspond to the place value in my JSON object. Now I need to compare the place of each element in the secont array with the value of ID in the JSON object and if the match I have to replace the value of PLACE with the element from the array.
I am having problems doing the comparison. Any guidelines? What I come up with:
foreach($ids as $index=>$id) { //the array
$id = (int) $id;
foreach ($obj as $key=>$value) { //the JSON objects
foreach ($value as $k=>$v){
if ($id != '' && array_search($index, array_keys($ids)) == $value[$k]['id']) {
$value[$k]['place'] = $id;
file_put_contents($file, json_encode($ids));
} else { print "nope";}
} } }
That will be:
$array = [
'{"id":1,"place":2,"pic_name":"aaa.jpg"}',
'{"id":2,"place":5,"pic_name":"aab.jpg"}',
'{"id":3,"place":1,"pic_name":"aba.jpg"}',
'{"id":4,"place":3,"pic_name":"baa.jpg"}',
'{"id":5,"place":4,"pic_name":"abb.jpg"}'
];
$places = ["4","3","1","2","5"];
$array = array_map(function($item)
{
return json_decode($item, 1);
}, $array);
foreach($array as $i=>$jsonData)
{
if(false!==($place=array_search($jsonData['id'], $places)))
{
$array[$i]['place'] = $place+1;
}
}
$array = array_map('json_encode', $array);
//var_dump($array);
-with output like:
array(5) {
[0]=>
string(39) "{"id":1,"place":3,"pic_name":"aaa.jpg"}"
[1]=>
string(39) "{"id":2,"place":4,"pic_name":"aab.jpg"}"
[2]=>
string(39) "{"id":3,"place":2,"pic_name":"aba.jpg"}"
[3]=>
string(39) "{"id":4,"place":1,"pic_name":"baa.jpg"}"
[4]=>
string(39) "{"id":5,"place":5,"pic_name":"abb.jpg"}"
}

Read key of array two dimension

I try to read some keys of an array like
array(3) {
["poste5:"]=> array(3) { [0]=> string(7) "APPLE:" [1]=> string(5)
"demo1" [2]=> string(5) "demo2" }
["services:"]=> array(4) { [0]=> string(9) "orange" [1]=>
string(5) "demo3" [2]=> string(5) "demo4" [3]=> string(5) "demo1" }
["essai:"]=> array(2) { [0]=> string(6) "sd" } }
I try to read this name : poste5 , services , essai
If i use :
foreach ($this->aliasRead as $key => $value){
echo array_keys($this->aliasRead[$key]);
}
I have : Array()
But if i use :
foreach (array_keys($this->aliasRead) as $key => $value2) {
echo $value2;
}
I have poste5 , services , essai
I try to use with this loop foreach ($this->aliasRead as $key => $value){
because i have another traitment after.
How to collect this key of my first loop in this loop foreach ($this->aliasRead as $key => $value){ ?
You already have what you want here:
foreach ($this->aliasRead as $key => $value){
echo $key; // key of the value in the array
print_r($value); // value of $this->aliasRead[$key] which in turn is another array
}
Edit: The reason your second loop works is because of this: array_keys($this->aliasRead[$key]) returns a new array containing the keys of the old array as its values. So $myNewArray = array_keys($this->aliasRead[$key]) is the same as $myNewArray = array('poste5','services','essai'). So, when you loop over this new array like this:
foreach ($myNewArray as $key => $value2) {
echo $value2;
}
$value2 contains your values, which are the keys of your first array, and $key will be 0, 1 and 2 after each step through the loop.
Try this,
$keys = array_keys($this->aliasRead);
print_r($keys);
Or
$keys = array();
foreach ($this->aliasRead as $key => $value){
$keys[] = $key;
}
It's because you're trying to echo an array. This will always give you the string "Array". If you want to see the array's contents, try
var_dump(array_keys($this->aliasRead[$key]));
By the way, in the foreach statement you posted, $this->aliasRead[$key] will be the equal to $value. So this will work as well:
var_dump(array_keys($value));

Strange foreach behaviour after an object casting

I get stuck with a strange PHP behaviour after a cast. Here is the code :
$obj = new stdClass();
$obj->{'0'} = "test";
$array = (array)$obj;
var_dump($array);
This code will output :
array(1) { ["0"]=> string(4) "test" }
Absolutely normal.
Now I add some code :
foreach ($array as $key => $value) {
$array[$key] = strtoupper($value);
}
var_dump($array);
This code outputs :
array(2) {
["0"]=>
string(4) "test"
[0]=>
string(4) "TEST"
}
Why my $key casted to int ?
If I try a simpler example :
$array = array("0" => "test");
foreach ($array as $key => $value) {
$array[$key] = strtoupper($value);
}
var_dump($array);
This will output :
array(1) { [0]=> string(4) "TEST" }
Does somebody know why there is a cast of my $key to int ?
Update
I tried to force to cast my key to string :
$array["{$key}"] = $value;
and
$array[(string)$key] = $value;
But they are inserted as int. So my question should be : is there a way to insert keys as string into an array?
I know that I can solve my problem by using a second array and dismiss strings :
$obj = new stdClass();
$obj->{'0'} = "test";
$array = (array)$obj;
$array2 = array();
foreach ($array as $key => $value) {
$array2[$key] = strtoupper($value);
}
But it would be nice to make it in a more beautiful way, conserving data type (and avoiding duplicating entries while iterating them as previously demonstrated).
From the PHP manual:
Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.
#cHao found a clean and working solution to convert an object to an array without foreach() matters. My example becomes :
$array = array();
$obj = new stdClass();
$obj->{'0'} = "test";
foreach ($obj as $key => $value) {
$array[$key] = strtoupper($value);
}
stdClass is iterable.
Thank you!

Categories