Create array from row objects in the same table :: PHP + SQL - php

I have an array like so
id | userID | item
1 ! 1 | {"property": 0, "property": "string"}
2 ! 1 | {"property": 4, "property": "string2"}
and I wish to return one array with like so:
[{
"property": 0,
"property": "string"
},
{
"property": 4,
"property": "string2"
}]
No matter what I try I cannot seem to get it to work properly. Either I get a whole string so number values get converted, or I get an object with \" everywhere. Currently I have this code
if ($query = $mysqli->query("SELECT item FROM userItems WHERE userID = 'id' "))
{
while ($row = $query->fetch_object())
{
$result->items[count($result)] = $row;
}
}
$test = stripslashes(json_encode($result->items));
which returns this ...
{"1":{"item":"{"property":"0","property":"string"}"}}
Been trying to solve it for hours and can't get it right

I tried your code and there're two main things:
you're building an array of associative arrays but associative array tends to overwrite identical associative keys with the latter in your code - in your case both keys are property,
the data you're retrieving from DB (userItems.item) already seems to be JSON encoded so you need to call json_decode() somewhere instead of calling json_encode() again; decoding your $row->item ($result->items[count($result)] = json_decode($row->item);) seems to do the trick.
Just as a sidenote you should consider wrapping your id parameter in SQL query into mysqli_real_escape_string() or so.
Let me know if that helped and you see the desired result now.

Related

Replacing a JSON array in MySQL in PHP

I am trying to replace data in a JSON array inside a JSON array in my MySQL Database.
The array looks like this:
{"slug": "SLUG","price": "{"44":12,"_default":12}", "test": "TEST"}
Now I would like to update the two fields inside the price array.
I am using the following code to be able to replace the price array with a string or number, but I am not able to replace it with another array:
$sql = "UPDATE products SET productDynamicFields = JSON_REPLACE(productDynamicFields,'$.price', '$test')
Where productSlug = '$productSlug'";
$result = mysqli_query($link,$sql);
As you can see I am using a variable called $test.
I tried giving the variable the following value: $test = ['44' => 13, '_default' => 13]; and then encoding it like this: $test = json_encode($test);
But now in my database it looks like this:
"price": "{\"44\":13,\"_default\":13}
I now tried using JSON_UNESCAPED_SLASHES with no success.
What can I do to achieve the array inside the array?
Rather than generating json from php and attempting to pass it to MySQL, you would better use MySQL function json_object() to generate a valid json object:
update t
set js = json_replace(js, '$.price', json_object('44', 13, '_default', 13))
Demo on DB Fiddlde:
create table t (js json);
insert into t values('{"slug": "SLUG","price": {"44":12,"_default":12}, "test": "TEST"}');
update t
set js = json_replace(js, '$.price', json_object('44', 13, '_default', 13));
select * from t
| js |
| :-------------------------------------------------------------------- |
| {"slug": "SLUG", "test": "TEST", "price": {"44": 13, "_default": 13}} |
Note:
The array looks like this:
{"slug": "SLUG","price": "{"44":12,"_default":12}", "test": "TEST"}
this is a json object (with an embedded json object under key "price"), not a json array
you had additional double quotes around the embedded object that made the json invalid, I assumed that was a typo and removed them

JSON object with array header

this question comes from the posting I found here:
DataTables Multiple Tables from Multiple JSON Arrays
I'd like to know the simplest and best way to generate the JSON below. I can see the pattern is 'JSON object -> Array Header -> Array -> JSON object' but I do not know how to do this in PHP, from a mySQLi query result. I imagine having a mySQL table with a 'policies' and 'services' column so the query might look something like:
Select name, id, score, type from myTable where type = 'policies' and
type = 'services'
And the result would come back something like:
name id score type
A 1 0 policies
B 2 0 services
But then how would I take that query and generate this JSON in php?
{
"Policies": [
{
"name": "A",
"id": "1",
"score": "0"
}
],
"Services": [
{
"name": "B",
"id": "2",
"score": "0"
}
]
}
Thanks for your help!
Start by creating the new empty array.
Then, iterate through the result and add it in the correct sub-array:
$new = [];
foreach ($result as $item) {
// Uppercase the first character
$type = ucfirst($item['type']);
if (!isset($new[$type])) {
// This type doesn't exist in the new array yet, let's create it.
$new[$type] = [];
}
// Add the item
$new[$type][] = $item;
}
// Output it as json
echo json_encode($new, JSON_PRETTY_PRINT);
The above code will also work if new types are added to the database.
PS. The JSON_PRETTY_PRINT argument is just to make the json string a bit more readable while developing. When everything looks good, you can remove it.

Cannot retrieve query.start-index variable from Google Analytics Core Reporting Results JSON Object

I am building a Google Analytics Dashboard and have it pretty completed, but am just totally stumped on this one thing that is really hanging me up.
When I query the GA Core Reporting API for a dataset, I successfully get and am able to display results and everything works fine EXCEPT I am not able to query the JSON object for the "start-index". That is, the first row that it will display (default = 1, but GA only returns 10k rows at a time, so if you have a data set with >10k rows, this becomes critically important!).
To attempt to get this integer, I use
$start = $results->query.start-index;
and as a check to make sure I am not insane, "max-results" is right next to "start-index" in the JSON object and this works fine:
$max = $results->totalResults;
Here is the GA JSON object (per https://developers.google.com/analytics/devguides/reporting/core/v3/reference#startIndex)
{
"kind": "analytics#gaData",
"id": string,
"selfLink": string,
"containsSampledData": boolean,
"query": {
"start-date": string,
"end-date": string,
"ids": string,
"dimensions": [
string
],
"metrics": [
string
],
"sort": [
string
],
"filters": string,
"segment": string,
"start-index": integer,
"max-results": integer
},
"itemsPerPage": integer,
"totalResults": integer,
"previousLink": string,
"nextLink": string,
"profileInfo": {
"profileId": string,
"accountId": string,
"webPropertyId": string,
"internalWebPropertyId": string,
"profileName": string,
"tableId": string
},
"columnHeaders": [
{
"name": string,
"columnType": string,
"dataType": string
}
],
"rows": [
[
string
]
],
"totalsForAllResults": [
{
metricName: string,
...
}
]
}
Help! Thanks in advance
Property names in PHP can contain neither . nor -. Your code is interpreted as a string concatenation of an array with the result of a mathematical subtraction of two strings (don't even begin to try and understand this if you don't see what I mean from that description).
PHP is actually a complete pain in the rear-end when it comes to this point, you have to force it to convert the decoded data to associative arrays instead of objects by passing TRUE to the second argument of json_decode(). You can then access the data by array key:
E.g.
$results = json_decode($jsonString, TRUE);
$start = $results['query']['start-date'];
So I am still not entirely sure why this works the way it does, but I've successfully pulled the correct start-index number using the following function:
function getStartIndex(&$results) {
$query = $results->getQuery();
foreach ($query as $paramName => $value) {
if($paramName == "start-index")
$startIndex = $value;
}
return $startIndex;
}
This essentially loops through the entire $query associative array until it finds one where the parameter matches "start-index" and then returns the value.

Getting back strange JSON array from MySQL

I have the following PHP code:
$data=mysql_query("SELECT * FROM notes WHERE rootNoteId='$noteId'");
$mainArray;
while($result = mysql_fetch_array($data))
{
$mainArray[]=$result;
}
$sendback = array(
"mainArray" => $mainArray
);
sendResponse(200, json_encode($sendback));
My table 'notes' has the following fields:
'noteId'
'authorName'
'noteBody'
However my return JSON string has the following format:
{
"0": "3",
"1": "Moe Bit",
"2": "Sub sub ",
"noteId": "3",
"authorName": "Moe Bit",
"noteBody": "Sub sub "
}
Why is it adding 0,1,2 indexes for the array with duplicate values of my table fields? I just want noteId, authorName, and noteBody-I'm not sure where it's coming up with "0","1","2".
mysql_fetch_array() in it's default "mode" fetches the result as associative & numeric array. So you get field names (what you want) and numeric indexes (the numbers you don't want).
To solve this pass the constant "MYSQL_ASSOC" as the second parameter to "mysql_fetch_array" or use the mysql_fetch_assoc() function.
try either mysql_fetch_assoc or mysql_fetch_object

php how to store and read json data via mysql?

php how to store and read json data via mysql?
mysql_query("INSERT INTO text (data) VALUES (json_encode('id' => $uid, 'value' => yes))");
then, how to update data value? read out the data, then insert it with an json_encode and decode process, or only easy way update?
[{"id": "1", "value": "yes"}]
then insert another change to [{"id": "1", "value": "yes"},{"id": "2", "value": "yes"}]...
Or even if a long long value.
[{"id": "1", "value": "yes"},{"id": "2", "value": "yes"}...{"id": "10000", "value": "yes"}]
then update another one, change to [{"id": "1", "value": "yes"},{"id": "2", "value": "yes"}...{"id": "10000", "value": "yes"},{"id": "10001", "value": "yes"}]
I wanna to ask, how to do this mysql query processing more wiser and efficiently? Thanks for more suggestion.
Technically, you are going the wrong way with that. MySQL is used to store each of your ID/VALUE seperately. For the sake of NOT changing your code we'll look at your solution first but then i'll explain the "better" way of doing it.
First, you need to make your JSON as a variable, not part of your SQL:
mysql_query("INSERT INTO text (data) VALUES (".mysql_real_escape_string(array(json_encode('id' => $uid, 'value' => 'yes'))).")");
instead of
mysql_query("INSERT INTO text (data) VALUES (json_encode('id' => $uid, 'value' => yes))");
This first part will allow you to at least instead the data correctly into mysql. I am ASSUMING your table has an ID and that you will be using it to update or delete
When you retrieve your data, you can json_decode the $row['data'] to get your data back from the row and work with it. To update it, just do:
mysql_query("UPDATE text SET data = "'.mysql_real_escape_string(json_encode($myJsonToBeData)).'" WHERE rowid = '.$myrowid)
Now, for the RIGHT way to do this:
The right way to do this would be to have these fields into your table: ID, JSONID, JSONVALUE and use this SQL instead:
SELECT * FROM text WHERE id = $rowid
INSERT INTO text VALUES(NULL, $jsonid, $jsonvalue)
UPDATE text SET jsonid = $jsonid, jsondata = $jsondata
This is pretty basic, but it will allow you to have any number of entries in your database that make it searchable, indexed, sortable, queryable, etc...
You can do this more efficiently by NOT storing JSON in a single field but by creating a proper MySQL table with the JSON object's property names as field names.
Storing a text-string encoded representation of your data in a database completely destroys the point of using databases in the first place.
Yes but....WordPress stores a lot of its data as encoded JSON strings, such as the user capabilities. Storing an array as a discrete bit of data takes away having to do multiple reads on the database and allows you to get a lot of data on one read. If you never see the need to SELECT the individual parts of the JSON string I don't see why it isn't acceptable to do it this way. MySQL must think so too because it has functions to allow a SELECT on the individual fields within a JSON string if you so desired (see MySQL EXPLAIN keyword). But I do agree if you were going to do a lot of SELECTs on a field it should have one of its own. It all depends on how you are going to use the data.
Assuming you want to store the JSON string as a text or varchar datatype in MySQL, you can simply just escape the JSON string like so:
Storing
$object = new stdClass();
$object->key_a = "Value A";
$object->key_b = "Value B";
$storable_json_string = trim( addslashes( json_encode( $object ) ) );
// `$storable_json_string` contains an ugly invalid JSON
mysqli_query( "INSERT INTO table_a (column_a) VALUES ('{$storable_json_string}')" );
Reading
// read from the database
$result = mysqli_query( "SELECT column_a FROM table_a" );
$row = $result->fetch_object();
// makeover the ugly invalid JSON into a machine readable valid JSON
$valid_json_string = substr( stripslashes( $row->column_a ), 1, -1 );
// makes the JSON as a PHP object
$readable_json_object = json_decode( $valid_json_string );
echo $readable_json_object->key_a; // Value A
This could be not that secure but at least these should give you some stepping stones.

Categories