auto-incrementing ID on my JSON array - php

I've been trying to do this for a while now and I just can't seem to get it right. One post got me very close but not quite there because my of JSON's hierarchy. (it's an assignment and this hierarchy is mandatory.)
What I do right now is submit info from one page, POST it to my php on another page, save it in an array there, json_encode that array and write that to my JSON file.
Here is my watered-down code, hopefully getting rid of most unnecessary code:
<?php
$filename = "json/exercises.json";
$filesize = filesize($filename);
$fp = fopen($filename, "r+");
#Accept the submitted form
$exLanguage = $_POST['exLanguage'];
$exTitle = $_POST['exTitle'];
$exStuff = $_POST['exStuff'];
#write to JSON with an incrementing ID
if (file_get_contents($filename) == "") {
$exercise = array (
"id" => 1,
"lang" => $exLanguage,
"title" => $exTitle,
"main_object" =>
[
"exStuff" => $exStuff
]
);
$exercise_json = json_encode($exercise, JSON_PRETTY_PRINT);
file_put_contents($filename, $exercise_json, FILE_APPEND);
} else {
#Get the last set ID
$jsonid = json_decode(fread($fp, $filesize), true);
$last = end($jsonid);
$title = prev($jsonid);
$lang = prev($jsonid);
$id = prev($jsonid);
$exercise = array (
"id" => ++$id,
"lang" => $exLanguage,
"title" => $exTitle,
"main_object" =>
[
"exStuff" => $exStuff
]
);
$exercise_json = json_encode($exercise, JSON_PRETTY_PRINT);
file_put_contents($filename, $exercise_json, FILE_APPEND);
}
?>
now what this does is if my json is empty it adds the first array correctly with the ID at 1. Then if I try to add to my json again it adds it correctly with the ID at 2. But any more attempted writes to the JSON will give me these errors:
Warning: end() expects parameter 1 to be array, null given
Warning: prev() expects parameter 1 to be array, null given
Warning: prev() expects parameter 1 to be array, null given
Warning: prev() expects parameter 1 to be array, null given
I tried doing a
$reset = reset($jsonid);
after writing to file but that didn't work, just gave me another error on the 3rd write for the reset being given a null too.
Can anyone please tell me how to get this too work? Or if there is a much easier way of getting this done?

Understand JSON format first. Its a collection of Objects which means attribute: value pair wrapped in {} and separated by comma , and then again wrapped in {} OR [] at top level.
Your JSON structure is incomplete or corrupted. What you are doing currently will create JSON in following format in your JSON file:
{ "id": 1, "lang": "as", "title": "asdsad" }
{ "id": 2, "lang": "as", "title": "asdsad" }
{ "id": 3, "lang": "as", "title": "asdsad" }
{ "id": 4, "lang": "as", "title": "asdsad" }
So json_decode will return null in this case because of invalid JSON format.
You need to keep appending your new JSON in existing JSON such that above format will become like this:
[
{ "id": 1, "lang": "as", "title": "asdsad" },
{ "id": 2, "lang": "as", "title": "asdsad" },
{ "id": 3, "lang": "as", "title": "asdsad" },
{ "id": 4, "lang": "as", "title": "asdsad" }
]
Which means your else block is incorrect. Use following code in else block:
$jsonid = json_decode(file_get_contents($filename), true);
$last = end($jsonid);
$id = $last['id'];
$jsonid[] = array (
"id" => ++$id,
"lang" => $exLanguage,
"title" => $exTitle,
"main_object" => array("exStuff" => $exStuff)
);
$exercise_json = json_encode($jsonid, JSON_PRETTY_PRINT);
file_put_contents($filename, $exercise_json, FILE_APPEND);
I hope you are not bound to use that incorrect/corrupted JSON format. That will not work with json_decode() in any case.

Related

Convert array to int php

Code:
public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
$valornovo = $args['sacar'];
$user = User::where('id', $args['id']);
$fields2 = 'saldo';
$fields = $getSelectFields();
$valorantigo = (object) $user->with($fields->getRelations())->select($fields2)->first();
$foo = json_decode($valorantigo, true);
$foo2 = array_map('intval', $foo);
return $foo2;
}
It returns the correct value. But I need to convert it to a number (int) to do a subtraction operation.
I converted to array with this:
$foo = json_decode($valorantigo, true);
Now I need to convert to int. I tried (int) and I couldn't, it returns null.
Edit: what I want is that it returns the value, however it is an integer:
https://prnt.sc/t0ehbd
Vardump:
https://prnt.sc/t0ehhf
I don't know how yet, but he gets exactly the amount I need. But I can't do operations because it is an array
I just want this value, not the whole array https://prnt.sc/t0es0f
json_decode($valorantigo, true) takes a JSON encoded string and returns an associative array.
Based on what I can tell from your data, your associative array contains strings as keys and associative arrays as values as follows:
{
"data": {
"users": [
{
"name": "Rodrigo Cardoso",
"email": "rodrigo.cardoso#imasters.com.br",
"saldo": 10,
"id": 3,
"company": null
},
{
"name": "Reinaldo Silotto",
"email": "reinaldo.silotto#imasters.com.br",
"saldo": 0,
"id": 2,
"company": null
},
{
"name": "Alefe Souza",
"email": "contact#alefesouza.com",
"saldo": 0,
"id": 1,
"company": null
}
]
}
}
My guess is that you want to return the value of a specific key of a nested array, which you can do like this:
array_map(function ($user) {
return $user['saldo'];
}, $foo['data']['users']);
This will return an array with the saldo value for each user.
array_values — Return all the values of an array :
$array = array("id" => 4, "days" => 64);
print_r(array_values($array));
The above example will output:
Array
(
[0] => 4
[1] => 64
)

How to use an JSON return from a php query into an foreach loop?

i am using Codeigniter and inside a function i call a controller to return data which I want to use in an foreach to built an insert statement.
The JSON returned looks like this:
{
"Data": [
{
"id": "743",
"day": "1",
"day_type": "Party",
"day_dresscode": "Black",
"day_p_id": "1",
"description": "Test desc",
"name": "test"
},
{
"id": "743",
"day": "2",
"day_type": "Party",
"day_dresscode": "White",
"day_p_id": "1",
"description": "Test desc 1",
"name": "test 2"
}
]
}
my php looks like below:
// This where i got my JSON
$datavar = $this->model->get_json_data($id,$code);
// This is to decode the JSON
$datavar_decode['Data'] = json_decode($datavar,true);
Below is my foreach:
$i = 1;
foreach($datavar_decode['Data'] as $data):
$data_insert = array(
'val1' => $data['val1'],
'val2' => $data['val2'],
'val3' => $data['val3'],
'val4' => $data['val4']
);
$this->db->insert('mssqltable', $data_insert);
$i++;
endforeach;
It gives me below error:
Invalid argument supplied for foreach()
Don't use json.
You're problem is that you are returning an array of objects, and that's the behavior you get from $query->result() or if you use $query->row() then you get an object representing a single row.
In order to return an array, use $query->row_array() for a single row, or for multiple records returned you would use $query->result_array().
See all the details: https://www.codeigniter.com/user_guide/database/results.html
You can try this code to test that your $datavar_decode['Data'] doesn't allocate an empty array when you've got nothing to begin with anyway.
if (is_array($datavar_decode['Data']) || is_object($datavar_decode['Data']))
{
foreach ($datavar_decode['Data'] as $data)
{
...
}
}

How to decode multi-layers nested JSON String and display in PHP?

I know how to decode a JSON string and get the data from one dimensional array but how to get the data from the nested array?
Below is my code:
$data = json_decode($json);
and below is the JSON return value:
{
"area_metadata": [
{
"name": "A",
"label_location": {
"latitude": 1,
"longitude": 1
}
},
{
"name": "B",
"label_location": {
"latitude": 1,
"longitude": 1
}
}
],
"items": [
{
"update_timestamp": "2017-05-02T09:51:20+08:00",
"timestamp": "2017-05-02T09:31:00+08:00",
},
"locations": [
{
"area": "A",
"weather": "Showers"
},
{
"area": "B",
"weather": "Cloudy"
}
]
}
]}
I had tested:
echo $data->items->locations[0]->area;
but I got this error
Trying to get property of non-object
Also,I tried to convert JSON into array instead of object:
$data = json_decode($json,true);
if (isset($data))
{
foreach ($data->items->locations as $location)
{
if (empty($location["area"])) { continue; }
if ($location["area"] == "A")
{
echo $location["weather"];
}
}
}
but it also not working.
Could anyone can advise which step that I did wrongly?
Thanks!
Edited:
Below is the pastebin link with full JSON content.
https://pastebin.com/cewszSZD
The JSON you provided (in your question) is malformed and using json_decode() on it will result in NULL. Thus nothing will happen when you try to access the decoded object because it doesn't exist.
The full JSON you provided is valid and the reason why your code didn't yield any results is because in items there is an "inner"-array:
(...)
["items"] => array(1) {
[0] => array(4) {
// ^^^^^^^^^^^^^^^^^
["update_timestamp"] => string(25) "2017-05-02T09:21:18+08:00"
["timestamp"] => string(25) "2017-05-02T09:07:00+08:00"
["valid_period"] => array(2) {
["start"] => string(25) "2017-05-02T09:00:00+08:00"
["end"] => string(25) "2017-05-02T11:00:00+08:00"
}
["forecasts"] => array(47) {
[0] => array(2) {
["area"] => string(10) "Ang Mo Kio"
["forecast"] => string(19) "Partly Cloudy (Day)"
}
(...)
You'll have to access that array through key 0, for arrays it will look like this:
$data = json_decode($json, true);
echo $data['items'][0]['forecasts'][0]['area'];
// ^^^
And for objects like this:
$data = json_decode($json);
echo $data->items[0]->forecasts[0]->area;
// ^^^
The second 0 changes the location (the different arrays in the forecasts array).
You can check the output here (array approach) and here (object approach).
It would be easier to help if you post all the JSON data or link to a screenshot of it. Try:
$items[0]['locations'][0]['area'];
Single quotes on strings, no quotes on numbers.

PHP: setting a number as key in associative array

I'm trying to recreate json from a DB, for the client side. Unfortunately some of the keys in the json are numbers, which work fine in javascript, however as a result PHP keeps treating them as numeric instead of associative arrays. each key is for a document. let me show you:
PHP:
$jsonobj;
while ($row = mysql_fetch_assoc($ms)) {
$key = strval($row["localcardid"]);
$jsonobj[$key] = json_decode($row["json"]);
}
// $jsonobj ist still a numeric array
echo json_encode($jsonobj);
the resulting json should look like this:
{
"0": {
"terd": "10",
"id": 0,
"text": "",
"pos": 1,
"type": 0,
"divs": [
{},
{}
],
"front": 1
}
"1": {
"terd": "10",
"id": 0,
"text": "",
"pos": 1,
"type": 0,
"divs": [
{},
{}
],
"front": 1
}
}
One obvious solution would be to save the whole json without splitting in up. however that doesnt seem wise in regards to the db. i wanna be able to access each document seperately. using
$jsonobj = array ($key => json_decode($row["json"]));
obviously works, but unfortunately just for one key...
EDIT: for clarification*
in php: there's a difference between
array("a", "b", "c")
and
array ("1" => "a", "2" => "b", "3" => "c").
the latter, when done like this $array["1"] = "a" results in array("a") instead of array("1" => "a")
ANSWERED HERE
Try
echo json_encode((object)$jsonobj);
I believe if you pass the JSON_FORCE_OBJECT option, it should output the object with numeric indexes like you want:
$obj = json_encode($jsonObj, JSON_FORCE_OBJECT);
Example:
$array = array();
$array[0] = array('test' => 'yes', 'div' => 'first', 'span' => 'no');
$array[1] = array('test' => 'no', 'div' => 'second', 'span' => 'no');
$array[2] = array('test' => 'maybe', 'div' => 'third', 'span' => 'yes');
$obj = json_encode($array, JSON_FORCE_OBJECT);
echo $obj;
Output:
{
"0": {
"test": "yes",
"div": "first",
"span": "no"
},
"1": {
"test": "no",
"div": "second",
"span": "no"
},
"2": {
"test": "maybe",
"div": "third",
"span": "yes"
}
}
Simply save both inside a single entry in the database: the separate field values AND the whole json structure inside a separate column. This way you can search by single fields and still get the valid json structure for easy handling.
For setting a number as key in associative array we can use following code
$arr=array(); //declare array variable
$arr[121]='Item1';//assign Value
$arr[457]='Item2';
.
.
.
print_r($arr);//print value

PHP - JSON Data Parsing [duplicate]

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 11 months ago.
All,
I have the following JSON Data. I need help writing a function in PHP which takes a categoryid and returns all URLs belonging to it in an array.
Something like this::
<?php
function returnCategoryURLs(catId)
{
//Parse the JSON data here..
return URLArray;
}
?>
{
"jsondata": [
{
"categoryid": [
20
],
"url": "www.google.com"
},
{
"categoryid": [
20
],
"url": "www.yahoo.com"
},
{
"categoryid": [
30
],
"url": "www.cnn.com"
},
{
"categoryid": [
30
],
"url": "www.time.com"
},
{
"categoryid": [
5,
6,
30
],
"url": "www.microsoft.com"
},
{
"categoryid": [
30
],
"url": "www.freshmeat.com"
}
]
}
Thanks
What about something like this :
You first use json_decode, which is php's built-in function to decode JSON data :
$json = '{
...
}';
$data = json_decode($json);
Here, you can seen what PHP kind of data (i.e. objects, arrays, ...) the decoding of the JSON string gave you, using, for example :
var_dump($data);
And, then, you loop over the data items, searching in each element's categoryid if the $catId you are searching for is in the list -- in_array helps doing that :
$catId = 30;
$urls = array();
foreach ($data->jsondata as $d) {
if (in_array($catId, $d->categoryid)) {
$urls[] = $d->url;
}
}
And, each time you find a match, add the url to an array...
Which means that, at the end of the loop, you have the list of URLs :
var_dump($urls);
Gives you, in this example :
array
0 => string 'www.cnn.com' (length=11)
1 => string 'www.time.com' (length=12)
2 => string 'www.microsoft.com' (length=17)
3 => string 'www.freshmeat.com' (length=17)
Up to you to build from this -- there shouldn't be much left to do ;-)
Try the built-in json_decode function.

Categories