Mysql Update, replace and concatenate - php

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.

Related

how to store array values in single field database using json_encode in luman?

how to store array values in the single field database using json_encode in luman?
I get value from the request:
$qualification_id = array($request->input('qualification_id'));
my json encode line:
$serializedArr=json_encode( $qualification_id);
my insert query:
$result = DB::insert("insert into `borrower_registration`
(first_name,middle_name,last_name,city_id,
state_id,dob,marital_id,father_husband,
institute,qualification_id,graduated_id)
values ('$first_name',' $middle_name','$last_name','$city_id',
'$state_id ','$dob ',' $marital_id','$father_husband',
'$institute','$serializedArr','$graduated_id')");
I given sample input for the array 1,2,3,4 and using
print_r($qualification_id)
and get output like [1,2,3,4]
data type of the column qualification_id is int
I execute the code and it store in database as 0 .please give valuable suggestions.
Check if qualification_id column has JSON or TEXT format.

Parsing through database table and pulling out unique names

I have a table that is listed like this:
Table name: test
|--------------------|
|------Column 1------|
|--------------------|
|John,Raul,Matt,Tyler|
|Tim,Hannah----------|
|Zeke,Brady,Tim,Tyler|
|Elliot,Zeke---------|
|Matt,Andrew,Idda----|
...
And I need to get all of those names into a PHP array, without multiple cases of the same name.
Would I be better off getting each unique name via SQL, or should I just pull the column, and then parse through it via PHP?
The final PHP array would look like:
$test_array[0]="John"
$test_array[1]="Raul"
$test_array[2]="Matt"
$test_array[3]="Tyler"
$test_array[4]="Tim"
$test_array[5]="Hannah"
$test_array[6]="Zeke"
$test_array[7]="Brady"
$test_array[8]="Elliot"
$test_array[9]="Andrew"
$test_array[10]="Idda"
I'm not sure how I would parse each cell in the table. What would you guys do?
I agree it's best to normalize the database. However, given the situation you've described, I would perform the SQL select and use PHP to run through the results.
I'd initialize $results as an empty string:
$results = '';
Then I'd concatenate each row with $results:
$results .= $row;
Then I'd use explode() to put all of the names in an array:
$all_names = explode(',', $results);
Then I'd use array_unique() to reduces the $all_names array to unique values:
$unique_names = array_unique($all_names);
HTH.

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.

PHP MYSQL unserialize() issues

I have a "recruiter" table in my database which has different attributes and one of them is "Professions". "Professions" is a serialized array which I get from a multiple select form. And this works fine.
When I unserialize this attribute nothing is printed - no error, no text.
This is a code I was testing serialization with:
$sql = 'SELECT Company_name, Status, Size, Professions, Seniority_levels, Sector, Website, Location FROM Recruiter';
$query = mysql_query($sql, $con);
while($result = mysql_fetch_array($query, MYSQL_BOTH)){
$recruiters[] = array($result[0], $result[1], $result[2], $result[3], $result[4], $result[5], $result[6], $result[7]);
}
foreach($recruiters AS $recruiter){
$test = unserialize($recruiter[3]);
echo $test[0].'<br>';
}
So basically $test[0] prints nothing although the new lines are printed. Please help!
try printing the $test array and the $recruiters and the $recruiter arrays. See if the result is fine before the unserialisation of the data. If the query returns any data. Also try the while loop with mysql_fetch_assoc. Let me know of the results and if this solves the problem
test = unserialize($recruiter[3]); should become test = unserialize($recruiter[5]); since the sector field is the sixth column .
However what if somewhere in the future you might need to select rows where sectors equal smth ? serialize whont help you then so i suggest you have a look at a different implementation for the sector filed witch is called bitwize http://www.litfuel.net/tutorials/bitwise.htm
Edit
Asuming you hit the right column and the column contains a:1:{i:0;s:27: a:1:{i:0;s:27: a:38:{i:0;s:27: a:9:{i:0;s:39:, it looks like the serialized array is not fully saved in you're db, it's only part of it . So the unserialize function whont return you an array . Have a look at the length of the mysql field i assume you've set it smaller than you need so you're data is trimmed on insert/update .
Edit
a:1:{i:0;s:27: you're still missing the rest of the serialized array . s:27: means a string is following containint 27 characters, and you're serialized array stops there when it should look like
a:1:{i:0;s:27:"123456789012345678901234567";}
( a:1 stands for an array containing 1 value with it's content between {}, i:0; is the array key 0, s:27:""; stands for a string containing 27 characters as the value for the i:0 key ) .

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