I am using an API that returns search results as json. Then, I need to write this to a MYSQL table. I’ve done this successfully before, but this time the situation is different, and I think that’s because of the structure of the resulting array: the key names are dynamic in that, if no data exists for a particular key, the key is not listed in the array. Here is an example vardump of the array:
array
0 =>
array
'title' => string 'Funny but not funny' (length=19)
'body' => string 'by Daniel Doi-yesterday while eating at Curry House...
'url' => string 'http://danieldoi.com/2012/11/20/funny-but-not-funny/'
'source_site_name' => string 'WordPress.com' (length=13)
'source_site_url' => string 'http://www.wordpress.com' (length=24)
'query_topic' => string 'thanksgiving' (length=12)
'query_string' => string 'blogs=on&topic=thanksgiving&output=json' (length=39)
1 =>
array
'title' => string 'Travel Easy this Holiday Season...' (length=34)
'body' => string 'Give yourself a few gifts and get this holiday season off...
'url' => string 'http://facadebeauty.wordpress.com/2012/11/20
'date_published' => string 'Tue, 20 Nov 2012 18:22:35 +0000' (length=31)
'date_published_stamp' => string '1353435755' (length=10)
Notice how the order/inclusion of the keys is subject to change.
My proposed solution was to use the array keys as column names, turning them into a variable to use in a query statement, but this isn’t working for me. Here’s my attempt:
$jsonString = file_get_contents("http://search-query-URL&output=json");
$array = json_decode($jsonString, true);
// database connection code snipped out here
$table = "results";
foreach($array as $arr_value) {
foreach ($arr_value as $value) {
$colName = key($arr_value);
$colValue = ($value);
$insert="INSERT INTO $table ($colName) VALUES ('$colValue')";
mysql_query($insert) OR die(mysql_error());
next($arr_value);
}
}
Any suggestions on where to look next? Thank you!
UPDATE 11/27:
Here I am trying to adapt David’s suggestion. I’m receiving the following error: “Database Connection Error (1110) Column ‘title’ specified twice on query.”
Here’s my code as it stands now:
$mysqli = mysqli_connect("localhost");
mysqli_select_db($mysqli, "mydatabase");
foreach ($array as $column) {
foreach ($column as $key => $value) {
$cols[] = $key;
$vals[] = mysqli_real_escape_string($mysqli, $value);
}
}
$colnames = "`".implode("`, `", $cols)."`";
$colvals = "'".implode("', '", $vals)."'";
$mysql = mysqli_query($mysqli, "INSERT INTO $table ($colnames) VALUES ($colvals)") or die('Database Connection Error ('.mysqli_errno($mysqli).') '.mysqli_error($mysqli). " on query: INSERT INTO $table ($colnames) VALUES ($colvals)");
mysqli_close($mysqli);
if ($mysql)
return TRUE;
else return FALSE;
Final Upate – WORKING!
It’s working. Here’s what we’ve got:
$mysqli = mysqli_connect("localhost");
mysqli_select_db($mysqli, "mydatabase");
foreach ($array as $column) {
foreach ($column as $key => $value) {
$cols[] = $key;
$vals[] = mysqli_real_escape_string($mysqli, $value);
}
$colnames = "`".implode("`, `", $cols)."`";
$colvals = "'".implode("', '", $vals)."'";
$mysql = mysqli_query($mysqli, "INSERT INTO $table ($colnames) VALUES ($colvals)") or die('Database Connection Error ('.mysqli_errno($mysqli).') '.mysqli_error($mysqli). " on query: INSERT INTO $table ($colnames) VALUES ($colvals)");
unset($cols, $vals);
}
mysqli_close($mysqli);
if ($mysql)
return TRUE;
else return FALSE;
I actually have just this function sitting around because I use it all the time. What this does: pool all the associative pairs in your array for insertion into the table, and puts them in as a single insert. To be clear: this isn’t what you’re doing above, as it looks like you’re trying to insert each value in its own insert, which would probably give you way more rows than you want.
As MarcB says above, there is a risk that your target table won’t have a column that your results show. But we are sanitizing the insertion (with
mysqli_real_escape_string) so we shouldn’t have issues with injections vulnerabilities.