php how to store and read json data via mysql? - php

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.

Related

How to store a Json data in one field?

I know this question has been asked a lot and I have researched, trust me.
I have a Json file with multi variables in it. I want to take that Json file and store it in a single BLOB field on MySql Database.
I did json_decode() but when I try to store it, PHP gives me an error because json_decode() returns a php array but bindParam wants a string varaible.
I tried implode(",", json_decode($data,true)) but it didn't work.
Can you help me please...
My JSON file looks like this;
[
{ "xyz": "abc",
"izd": 1
},
{ "xyz": "abc",
"izd": 1
},
{ "xyz": "abc",
"izd": 1
}]
My PHP code is like this;
$json = $_POST["jsonfile"];
$jsondata = json_decode($json,true);
$implodedjsondata = implode(",",$jsondata); // In here, php gets error in impode ( Error : Notice: Array to string conversion)
$Query = $conn->prepare("INSERT INTO table1(somedata) VALUES(:data)");
$Query->bindParam(':data',$implodedjsondata); // In case of not using implode, this line gets error( Error : Notice: Array to string conversion)
$Query->execute();
Thanks...
its already a json? don't do anything with it, insert it as-is. and use bindValue, bindParam is an optimization thing when you have a lot of data you need to change fast when loop-executing a statement..
$json = $_POST["jsonfile"];
$Query = $conn->prepare("INSERT INTO table1(somedata) VALUES(:data)");
$Query->bindValue(':data',$json); // In case of not using implode, this line gets error( Error : Notice: Array to string conversion)
$Query->execute();

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

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.

Mysql Update, replace and concatenate

I have a php array like the one below.
$arr = array(
array(
"date"=>date('Y-m-d'),
"message"=>"test message 1",
"from_id"=>21,
"to_id"=>14
),
array(
"date"=>date('Y-m-d'),
"message"=>"test message 2",
"from_id"=>23,
"to_id"=>12
)
);
I do a json_encode on this array to convert it json.
$jsonarr = json_encode($arr);
Output of $jsonarr:
[
{"date":"2012-11-22","message":"test message 1","from_id":21,"to_id":14},
{"date":"2012-11-22","message":"test message 2","from_id":23,"to_id":12}
]
After that i insert this in mysql table. Everything is fine till here.
Now i have to update this with another json by concatenation.
Another JSON:
[
{"date":"2012-11-22","message":"test message 3","from_id":28,"to_id":2},
{"date":"2012-11-22","message":"test message 4","from_id":53,"to_id":72}
]
And i want the field in my mysql table to display like this:
[
{"date":"2012-11-22","message":"test message 1","from_id":21,"to_id":14},
{"date":"2012-11-22","message":"test message 2","from_id":23,"to_id":12},
{"date":"2012-11-22","message":"test message 3","from_id":28,"to_id":2},
{"date":"2012-11-22","message":"test message 4","from_id":53,"to_id":72}
]
How can i write an UPDATE query for this.
I can do this by using 2 queries. One select query then formatting the field and later updating. But can this be achieved with one query ?
The solution to your immediate problem is this:
MySQL does not natively support JSON values. You need to fetch the value from the database:
SELECT FOR UPDATE my_json_field
FROM my_table
WHERE id = 555;
Then modify it in the PHP script:
$my_array = json_decode($value_of_my_json_field);
$my_array = array_merge($my_array, $arr);
$value_of_my_json_field = json_encode($my_array);
Then update it in the DB:
UPDATE my_table
SET my_json_field = :value_of_my_json_field
WHERE id = 555;
Make sure this happens in a transaction. Also, you need to use the InnoDB storage engine.
But the more interesting question is why do you need to store JSON in the DB? Why not use a separate table:
Table: messages
id integer
date timestamp
from_id integer (this should be a foreign key)
to_id integer (this should be a foreign key)
Then you could simply insert into that table. That's the correct way of doing this. If you don't have a very good reason to use JSON, I would suggest getting rid of it.

MYSQL SELECT and JSON_ENCODE

I need to select a key from a json_encodED array from mysql..
SELECT * FROM json_field_table WHERE {var from JSON encoded array} = {expected value}
or something..
How I can do this?
PS.: Poor English, I know..
You'd have to use substring matching. MySQL doesn't have anything to deal with JSON data and treats it like it does any other piece of random text.
SELECT ... WHERE the_json_field LIKE '%"var":"value"%';
Well, Gabriel, despite the nature of your question. I am supposing, your problem might be, you need to read a JSON value and based on that values, you need to retrieve the record set from the table. If this is the case, here is your solution.
// A sample json string
$json = '{ "field1": "value1", "field2": "value2" }';
// Here we will convert the json string into readable assocative array
$json_array = json_decode($json,true);
//Next we will use it on a query
$query = "SELECT * json_field_table WHERE `".$json_array['field1']."` = 'Some Value' ";
//Execute the query
$result = mysql_query($query);
with numbers (integers) you can filter out values, with alphanumeric strings is more complicated as the value stored is "jsonencoded"
check my answer to 17955206

Save PHP array to MySQL?

What is a good way to save an array of data to a single mysql field?
Also once I query for that array in the mysql table, what is a good way to get it back into array form?
Is serialize and unserialize the answer?
There is no good way to store an array into a single field.
You need to examine your relational data and make the appropriate changes to your schema. See example below for a reference to this approach.
If you must save the array into a single field then the serialize() and unserialize() functions will do the trick. But you cannot perform queries on the actual content.
As an alternative to the serialization function there is also json_encode() and json_decode().
Consider the following array
$a = array(
1 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
2 => array(
'a' => 1,
'b' => 2,
'c' => 3
),
);
To save it in the database you need to create a table like this
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
$r = mysql_query(
'DROP TABLE IF EXISTS test');
$r = mysql_query(
'CREATE TABLE test (
id INTEGER UNSIGNED NOT NULL,
a INTEGER UNSIGNED NOT NULL,
b INTEGER UNSIGNED NOT NULL,
c INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (id)
)');
To work with the records you can perform queries such as these (and yes this is an example, beware!)
function getTest() {
$ret = array();
$c = connect();
$query = 'SELECT * FROM test';
$r = mysql_query($query,$c);
while ($o = mysql_fetch_array($r,MYSQL_ASSOC)) {
$ret[array_shift($o)] = $o;
}
mysql_close($c);
return $ret;
}
function putTest($t) {
$c = connect();
foreach ($t as $k => $v) {
$query = "INSERT INTO test (id,".
implode(',',array_keys($v)).
") VALUES ($k,".
implode(',',$v).
")";
$r = mysql_query($query,$c);
}
mysql_close($c);
}
putTest($a);
$b = getTest();
The connect() function returns a mysql connection resource
function connect() {
$c = mysql_connect($server, $username, $password);
mysql_select_db('test');
return $c;
}
Generally, yes, serialize and unserialize are the way to go.
If your data is something simple, though, saving as a comma-delimited string would probably be better for storage space. If you know that your array will just be a list of numbers, for example, then you should use implode/explode. It's the difference between 1,2,3 and a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}.
If not, then serialize and unserialize work for all cases.
Just use the serialize PHP function:
<?php
$myArray = array('1', '2');
$seralizedArray = serialize($myArray);
?>
However, if you are using simple arrays like that you might as well use implode and explode.Use a blank array instead of new.
Serialize/Unserialize array for storage in a DB
Visit http://php.net/manual/en/function.serialize.php
From the PHP Manual:
Look under "Return" on the page
Returns a string containing a byte-stream representation of value that can be stored anywhere.
Note that this is a binary string which may include null bytes, and needs to be stored and handled as such. For example, serialize() output should generally be stored in a BLOB field in a database, rather than a CHAR or TEXT field.
Note: If you want to store html into a blob, be sure to base64 encode it or it could break the serialize function.
Example encoding:
$YourSerializedData = base64_encode(serialize($theHTML));
$YourSerializedData is now ready to be stored in blob.
After getting data from blob you need to base64_decode then unserialize
Example decoding:
$theHTML = unserialize(base64_decode($YourSerializedData));
The best way, that I found to myself is save array as data string with separator characters
$array = array("value1", "value2", "value3", "...", "valuen");
$array_data = implode("array_separator", $array);
$query = "INSERT INTO my_tbl_name (id, array_data) VALUES(NULL,'" . $array_data . "');";
You can then search data, stored in your array with simple query
$query = "SELECT * FROM my_tbl_name WHERE array_data LIKE '%value3%'";
use explode() function to convert "array_data" string to array
$array = explode("array_separator", $array_data);
note that this is not working with multidimensional arrays and make sure that your "array_separator" is unique and had not exist in array values.
Be careful !!! if you just will take a form data and put in database, you will be in trap, becous the form data isn't SQL-safe ! you must handle your form value
with mysql_real_escape_string or if you use MySQLi mysqli::real_escape_string
or if value are integer or boolean cast (int) (boolean) on them
$number = (int)$_POST['number'];
$checked = (boolean) $_POST['checked'];
$name = mysql_real_escape_string($db_pt, $_POST['name']);
$email = mysqli_obj->real_escape_string($_POST['email']);
Serialize and unserialize are pretty common for that. You could also use JSON via json_encode and json_decode for a less PHP-specific format.
As mentioned before - If you do not need to search for data within the array, you can use serialize - but this is "php only". So I would recommend to use json_decode / json_encode - not only for performance but also for readability and portability (other languages such as javascript can handle json_encoded data).
Uhh, I don't know why everyone suggests serializing the array.
I say, the best way is to actually fit it into your database schema. I have no idea (and you gave no clues) about the actual semantic meaning of the data in your array, but there are generally two ways of storing sequences like that
create table mydata (
id int not null auto_increment primary key,
field1 int not null,
field2 int not null,
...
fieldN int not null
)
This way you are storing your array in a single row.
create table mydata (
id int not null auto_increment primary key,
...
)
create table myotherdata (
id int not null auto_increment primary key,
mydata_id int not null,
sequence int not null,
data int not null
)
The disadvantage of the first method is, obviously, that if you have many items in your array, working with that table will not be the most elegant thing. It is also impractical (possible, but quite inelegant as well - just make the columns nullable) to work with sequences of variable length.
For the second method, you can have sequences of any length, but of only one type. You can, of course, make that one type varchar or something and serialize the items of your array. Not the best thing to do, but certainly better, than serializing the whole array, right?
Either way, any of this methods gets a clear advantage of being able to access an arbitrary element of the sequence and you don't have to worry about serializing arrays and ugly things like that.
As for getting it back. Well, get the appropriate row/sequence of rows with a query and, well, use a loop.. right?
You can save your array as a json.
there is documentation for json data type: https://dev.mysql.com/doc/refman/5.7/en/json.html
I think this is the best solution, and will help you maintain your code more readable by avoiding crazy functions.
I expect this is helpful for you.
Yup, serialize/unserialize is what I've seen the most in many open source projects.
I would suggest using implode/explode with a character that you know will not be contained in any of the individual array items. Then store it in SQL as a string.
you can insert serialized object ( array ) to mysql , example serialize($object) and you can unserize object example unserialize($object)
check out the implode function, since the values are in an array, you want to put the values of the array into a mysql query that inserts the values into a table.
$query = "INSERT INto hardware (specifications) VALUES (".implode(",",$specifications).")";
If the values in the array are text values, you will need to add quotes
$query = "INSERT INto hardware (specifications) VALUES ("'.implode("','",$specifications)."')";
mysql_query($conn,$query);
Also, if you don't want duplicate values, switch the "INto" to "IGNORE" and only unique values will be inserted into the table.
UPDATE
Warning
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide. Alternatives to this function include:
mysqli_query
PDO::query()
Instead of saving it to the database, save it to a file and then call it later.
What many php apps do (like sugarcrm) is to just use var_export to echo all the data of the array to a file.
This is what I use to save my configurations data:
private function saveConfig() {
file_put_contents($this->_data['pathtocompileddata'],'<?php' . PHP_EOL . '$acs_confdata = ' . var_export($this->_data,true) . ';');
}
I think this is a better way to save your data!

Categories