Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to parse associative array

Status
Not open for further replies.

rogerte

Programmer
Nov 9, 2001
164
GB
I have a json_decoded string passed by AJAX array in the format :

Array (
[dta] => [
{ "a" : 1, "b" : "string" , "c" : ""},
{ "a" : 8, "b" : "string 2" , "c" : "12/12/2022"}
]
[vars] => [
7,
12
]
)

The items pointed to by dta need to be looped through to be added to a datatable. The number of individual "sub arrays" could be from 1 to 40.
The 2 integers pointed to by vars need to be assigned tro PHP variables.

This doen't follow any other associative array I have dealt with, so can any one point me at how to parse the above?
 
I'll post it when I am back home - but it'll be edited as the strings contain information that is identifiable.
 
Have just been talking to the guy who wrote the original javascript, which has never been used until now, and he says it's a mistake - the JSON output should have been:

[pre][
{
"id": 1,
"stext": "a string",
"sdate": "09/11/2023",
"bid": "7",
"cid": "6"
},
{
"id": 2,
"stext": "another string",
"sdate": " ",
"bid": "7",
"cid": "6"
}
]
[/pre]
but he reckons that an earlier, test, version had been loaded. (It's not a problem as a differnt system being used on the live version, that only passes one row at a time to the PHP)

Should make it easier to parse so I have thrown this together, but not had a chance to test it yet as I am away from my dev laptop (Probably wrong as I always have problems with PHP associated arrays!):

PHP:
<?php
header("Content-Type: application/json");
$data = file_get_contents("php://input");
$data_arr = json_decode($data, true);  // $data_arr should be an assoc. array
$rowsadded = 0;
foreach ($data_arr as $row) {
    $id = $row['id'];
    $text = $row["stext"];
    $sdate = $row["sdate"];
    $bid = $row["bid"];
    $cid = $row["cid"];
    if (strlen($sdate) < 6) {
        $date = NULL;
    } else {
        $date = date('Y-m-d', strtotime(str_replace('/', '-', $te)));
    }
    $rowsadded++;
}
 
By json syntax this is not an arrays of arrays, but an array of two (or more, if there are more records) record objects.
I'll test what I get out of it and report back later.

Chriss
 
Sorry, took a while-.

You have two ways to do this:
Code:
<?php
header('Content-Type: text/plain');

$json = <<<JSON
[
    {
        "id": 1,
        "stext": "a string",
        "sdate": "09/11/2023",
        "bid": "7",
        "cid": "6"
    },
    {
        "id": 2,
        "stext": "another string",
        "sdate": " ",
        "bid": "7",
        "cid": "6"
    }
]
JSON;

$arr1 = json_decode($json);
foreach($arr1 as $rowobj)
   echo "{$rowobj->id} , {$rowobj->stext} , {$rowobj->sdate} , {$rowobj->bid} , {$rowobj->cid}\r\n";

$arr2 = json_decode($json,TRUE);
foreach($arr2 as $rowarr)
   echo "{$rowarr['id']} , {$rowarr['stext']} , {$rowarr['sdate']} , {$rowarr['bid']} , {$rowarr['cid']}  \r\n";
?>

The first solution, not using TRUE in json_decode, converts to something that's closer to the original structure the JSON means, an array of row objects, not an array of row arrays, but the TRUE parameter turns objects to associative arrays.

There's no separate single values bid and cid in this JSON, instead they are repeated in both rows. I don't know if that's universally true, but the result is simply a list of row objects (or arrays, however you like to decode it) and not something with extra single properties and I'm pretty sure that's generally the case.

Chriss
 
Thanks for your help.
Back in the office and have loaded correct version of HTML document, and tried it out, but am now getting an error in the PHP foreach line.


However I tried your code and that worked as expected.

I have noted though that the print_r output is different to the output seen in your script.
In my PHP script I have added print_r statements to view output:
PHP:
header("Content-Type: application/json");

$data = file_get_contents("php://input");
echo("<pre>");
print_r($data);
echo("</pre><br>");

$data_arr = json_decode($data, TRUE);
echo("<pre>");
print_r($data_arr);
echo("</pre><br>");

$data_obj = json_decode($data);
echo("<pre>");
print_r($data_obj);
echo("</pre><br>");

Output is:

[pre]
"[{ \"id\" : 1, \"stext\" : \"a string\" , \"sdate\" : \"10/11/2023\" , \"bid\" : \"7\" , \"cid\" : \"6\"}]"


[{ "id" : 1, "stext" : "a string" , "sdate" : "10/11/2023" , "bid" : "7" , "cid" : "6"}]


[{ "id" : 1, "stext" : "a string" , "sdate" : "10/11/2023" , "bid" : "7" , "cid" : "6"}]
[/pre]
No difference between either array or object outputs.
Whereas for your script the output is
[pre]Array
(
[0] => stdClass Object
(
[id] => 1
[stext] => a string
[sdate] => 09/11/2023
[bid] => 7
[cid] => 6
)

[1] => stdClass Object
(
[id] => 2
[stext] => another string
[sdate] =>
[bid] => 7
[cid] => 6
)

)

and
Array
(
[0] => Array
(
[id] => 1
[stext] => a string
[sdate] => 09/11/2023
[bid] => 7
[cid] => 6
)

[1] => Array
(
[id] => 2
[stext] => another string
[sdate] =>
[bid] => 7
[cid] => 6
)

)

[/pre]

However if I then proceed to the

foreach ($data_arr as $row) {
$id = ...

etc
}

I get a "Warning: foreach() argument must be of type array|object, string given in..." error whichever format I use.

Looking at your code the line $json = <<<JSON is something I haven't come across before, and makes me wonder if I need to amend either the Javascript that sends the data, or the way it is converted in the PHP script
 
<<< is heredoc syntax, you can store multiline strings into variables that way. That's nothing you need to do, it's just my way of getting your posted JSON into a $json variable, that can also come from an AJAX request or whatever else, doesn#t matter.

The point of my code is demonstrating that you can choose how to parse the json.

It is more to the point of converting it to what it actually is: An array of row objcts. But you can also choose to decode it as associative array.

The two foreach loops of my code show you how different you then need to proceed with accessing the decoded array. Just do it as I do it and you don't get errors.

Chriss
 
header("Content-Type: application/json");

Do you have any idea of what you are doing here? You're stepping on your own foot. You wqant to DECODE the json, don't you? But you let PHP tell the swerver to serve your PHP output as JSON.

My code is just straight forward showing you code you need to get at the single elements and you can pick whether you like the code for $arr1 better, or for $arr2, that's just a matter of taste. But in both cases the outer level array is an array, and it's not an associative array, it has array elements 0 and 1 when the result has 2 records. And in one case the two array elements of that outer array are objects with field names that match the json names and in the other case the elements of the outer array are associative arrays.

You're likely misunderstanding json_decode and expecting it to turn the whole json into one associative array. That's not happening, it will turn json into the similar structure, the decoding isn't flattening whatever json string into one array only, you don't have a simplifier with json_decode, you have to dig into what you actually have, and your print_r output shows you exactly what's the difference of $arr1 and $arr2, nonce it's an array of 2 objects, once it's an array of 2 associative arrays.

Chriss
 

Sorry if I am being dense, but as I said new to JSON - have only ever used $_POST before, and I'm doing this to help out a local charity in my spare time so really appreciate your help.

I have been using Googled examples to set up the code, assuming it to be correct, so have removed the header statement.

Now, if ,instead of using :
Code:
$data = file_get_contents("php://input");
$data_arr = json_decode(trim($data), TRUE);
I directly paste the stringified data into the PHP script
Code:
$data = "[{ \"id\" : 1,  \"stext\" : \"a string\" , \"sdate\" : \"10/11/2023\" , \"bid\" : \"7\" , \"cid\" : \"6\"}]";
$data_arr = json_decode(trim($data), TRUE);
and run that everything works as expected and I can step through the array with no errors

var_dumps added after the json_decode showg $data_arr as string if $data is obtained by the file_get_contents call, but array if the stringified data is used directly.

Even more confused now.

 
I don't see how the stringified json is the same as your original posted json. Also, you could really just take my heredoc syntax to get the json or other json into a string variable to start further experimenting with different json.

Anyway, it's not your code to define the json, is it? You get it from some file, it seems, but where does that file come from. It's likely a webservice that returns json.

My code sample shows you that you can use both jason_decode(string) and then get an array of objecs, the objects within that array have to be adressed by $rowobj->fieldname and if you use json_decode(jsonstring,TRUE) you get an array of associative arrays and the elements of the associative arrays have to be addressed with $rowarr['fieldname'], and that's the difference.

If you have different json, and I mean totally structural different json, then you also will need differnt code to get to all the single elements you want to process in your further code. There is no single code that will cover all sorts of json strings you could have. The root of processing always is having json in a string variable and decode that into the PHP world with json_decode(jsonstring). But what you get from it depends on what the json is.

And print_r, as you know, gives you a rough overview of what you get.

I don''t get what you are really struggling with, still.

The first thing that I would say you need to get into more, is what the json notation actually means. Having a json_decode function is helpful in conjunction with print_r, if you're at least familiar with what that output means in the PHP world. But I get the impression you also struggle with that. Then what you really need is an elemnetary programming course.

Chriss
 
I've looked at the Javascript code and have found what the problem is!

It was building the array structure as a string, so was passing a stringified string

I've amended it and it now works ok.

Sorry if I have offended you, but thanks for the help
 
I didn't even understood where you have a problem. But good you solved it.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top