Let's read the image file into varialble picture:
$picture = addslashes(fread(fopen($image, "r"), filesize($image)));
This $picture you can easy insert into database table with no trouble.
*for example*: INSERT INTO $banners(banner) VALUES( $picture );
For some reason lets create an associative array $final:
$final["banner"] = $picture;
$final["place"] = something...
Later lets decompose $final and insert the obtained values into database:
$fields = ""; $values = "";
while (list($name, $value) = each( $final ))
{
$fields .= "$name, ";
$values .= "'$value', ";
}
// Cut trailing commas
$values_fields = ereg_replace(", $", "", $values_fields);
$values = ereg_replace(", $", "", $values);
// Execute query
$query = "INSERT INTO banners($values_fields) VALUES($values)";
$res = mysql_db_query($database, $query) or mysql_die();
Now MySQL warns "Something wrong" when comes to insert consecutive $value with $picture into database. Why?
First, don't destroy your data. Read it directly and keep the variable clean:
$picture = file_get_contents($image);
Next, prepare the data for insertion:
$final["banner"] = mysqli_real_escape_string($picture);
$final["place"] = $something;
Last, there is no need to loop through your array, since it only contains one record. You don't quote the values, causing an error.
$fields = "`" . implode("`, `", array_keys($final)) . "`";
$values = "'" . implode("', '", array_values($final)) . "'";
$query = "INSERT INTO banners ({$fields}) VALUES ({$values})";
$result = mysqli_query($database, $query) or die(mysqli_error($database));
I'm using MySQLi here, since the mysql_* functions are deprecated (as well as ereg_* functions).
If the code you posted here is exactly the one you are trying to run then please note that you are accumulating field names in $fields variable but "cut trailing commas" from $values_fields which is at this point empty. Putting empty $values_fields into your query might be the cause of mysql error.
Why are you doing addslashes()? Try to use mysql_real_escape_string() instead.
Also make sure that the type of the database column where you are trying to put your image into is BLOB or LONGBLOB.
You may find answer to this question Binary Data in MySQL relevant.
Related
Hi i been trying to inserting array's into MySql database
The problem i am having is that i have different datatypes and sometime data can be a 0 value, having () curly brackets, percentage value with % sign. I would like to know a way use some already built php function that can deal with this issues.
So here is what i have done so far:
$t = array('country_code' => $data->country_code,
'Name' => $data->Name,
'money' => $data->money,
'chanceToDie' => $data->death,
'age' => $cb->age)
/* FORMAT EXAMPLE
country_code = Africa (AF)
name = jack
chanceToDie = 5.5
age = 62
*/
$columns = implode(", ",array_keys($t));
//Tried
$values = implode(", ",array_values($t)); //Dont work
$values = "'".implode("', '",array_values($t))."'"; //Dont work
$sql = "INSERT INTO table ($columns) VALUES ($values)";
You need to quote each individual value and use array_values() instead of array_keys():
$values = '"' . implode('", "', array_values($t)) . '"';
However, this leaves you with an sql injection problem so you should really use a prepared statement.
In PDO you could use something like (assuming you control the keys and they are safe to use):
$values = ':' . implode(', :', array_keys($t));
// generates: ... VALUES(:country_code, :Name, :money, // etc
Now you can prepare and execute your query using the array to bind the values to the placeholders. See for example http://php.net/manual/en/pdo.prepared-statements.php (the 6th example).
Try to use the advantage of PDO prepared queries - it is more safe and convinient.
Your code may look like this:
$col_names = array_keys($t);
// filter column names before inserting to sql to prevent sql injection
array_filter($col_names, function($v){return preg_relace("#\W#", "_", $v);});
// generate placeholders list: ?,?,?,?
$placeholders = implode(',', array_fill(0, count(t), "?"));
$values = array_values($t);
$q = $pdo->prepare('insert into (' . implode(",", $col_names) . ') values (' . $placeholders . ')');
$q->execute($values);
PDO will deal with data types and correctly replace every placeholder with the corresponding value.
I'm trying to make code insert data into MYSQL from arrays
my problem is, it's not protected against SQL Injection.
I searched at every where ,How can i prevent it compeletly.
I looked for this question
How can I prevent SQL injection in PHP?
but i found two answers make me rethinking again.
https://stackoverflow.com/a/8255054/6523558
Every answer here covers only part of the problem.
In fact, there are four different query parts which we can add to it dynamically a string a number an identifier a syntax keyword.and prepared statements covers only 2 of them
https://stackoverflow.com/a/60442/6523558
I looked around for something will help me and this what i found
http://www.w3schools.com/sql/sql_injection.asp
http://www.w3schools.com/sql/sql_datatypes_general.asp
But nothing helped me to prevent it completely from my code.
I'm using this code to insert array data to MYSQL.
It's prevent it by using base64.
$tbname = "some_table";
$array1 = array("one"=>"1a","two"=>"2b");
$S1["add1"] = " (";
$S1["add2"] = " VALUES (";
foreach($array1 as $k1=>$n1){
if($n1 !== ""){
$S1["add1"] .= $k1 . ", ";
$S1["add2"] .= "'" . base64_encode($n1) . "', ";
};}
$S1["add1"] = substr($S1["add1"],0,-2);
$S1["add1"] .= ")";
//if($S1["add1"] == ")"){$_SESSION["sql_msg"] = "You have to put at least one input";} else {
$S1["add2"] = substr($S1["add2"],0,-2);
$S1["add2"] .= ")";
$sql = "INSERT INTO " . $tbname . $S1["add1"] . $S1["add2"];
//if ($conn->query($sql) === TRUE) {$_SESSION["sql_msg"] = "New record created successfully";
//} else {$_SESSION["sql_msg"] = "Error: " . $sql . "<br>" . $conn->error;};}
//ref1();
echo $sql;
Based on my article (which is more focused on disclosing bad and wrong practices), An SQL injection against which prepared statements won't help
The protection from SQL injection is actually simple, and can be formulated in just two statements:
use placeholders for the every data value
whitelist everything else
Given all that, you should
whitelist your table and field names
create a query consists placeholders and filtered out table and field names
send your variable array into execute.
For this purpose first define an array with all the allowed field names
$allowed = ["one","two"];
Then out of this array you will need to to create a SET statement for the INSERT query that should look like
one = :one, two = two:
For this you need a code like this
$allowed = ["one","two"];
$params = [];
$setStr = "";
foreach ($allowed as $key)
{
if (isset($array1[$key]))
{
$setStr .= "`".str_replace("`", "``", $key)."` = :".$key.",";
$params[$key] = $_POST[$key];
}
}
$setStr = rtrim($setStr, ",");
Note that we are also getting data values into distinct array
Finally, get your query from parts (given a table name is already hardcoded in you script) and then prepare and execute it using array with values
$tbname = "some_table";
$sql = "UPDATE `$tbname` SET $setStr";
$pdo->prepare($sql)->execute($params);
I guess the best way is by using
$sql = str_getcsv($sql,";")["0"];
before the execution to prevent any extra commands
I am trying to create a custom MVC framework in that I have a function which takes in array and triggers insert queries.
function insertFromArray($array, $table) {
foreach ($array as $key => $value) {
$fields[] = "`" . $key . "`";
$values[] = "'" . $value . "'";
}
$sql = "INSERT INTO `$table` (" . implode(",", $fields) . ") VALUES (" . implode(",", $values) . ")";
mysql_query($sql);
return (mysql_error()) ? mysql_error() : mysql_insert_id();
}
But when I get some mysql function instead of a string or integer my function does not work say for a filed name 'dateTime' I get value = NOW() in that case my query would be
INSERT INTO `$table` (`field1`, `field2`, `dateTime`) VALUES ('value1','value2','NOW()')
And this would throw error I want some generic solution so that my queries would run in either case if it is a string, number or if it is any mysql function.
I tried creating an array of all the functions and started with comparisons like if the starting of the $value matches any function from the array of mysql functions but I do not think that is a good way to do it, is there any better way to do that
$values[] = "'" . $value . "'";
The above line treats all values as strings and this causes the issue. Do not treat all values as strings and enclose them by single quotes.
You could even make the value part an array itself with 2 elements: one for the value and one for the type of the value (string, numeric, function, etc.) and would treat ech of them differently while creating the insert statement.
And pls use mysql or PDO instead of php's old mysql extension.
You could use an array to store your SQL keywords/function names. Then in your query string, you test to see if the current value is an SQL word or not. If it is, don't quote it, otherwise, you quote it.
Here is an example:
function is_sql_term($term)
{
$sql_terms = array('NOW()', 'DATE()', ...);
return in_array($term, $sql_terms) || preg_match("/\(.*\)/", $term);
}
Then you test as follows:
$values[] = is_sql_term($value) ? $value : "'" . $value . "'";
When i insert this type of array values directly into Mysql database, I got error like this
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':23:09Z, 36840bd430637, Success, 85.0, 11457922, 10.02, USD, X, M, 59106737WV831' at line 1
and myquery is
INSERT INTO `transaction`(TIMESTAMP, CORRELATIONID, ACK, VERSION, BUILD, AMT, CURRENCYCODE, AVSCODE, CVV2MATCH, TRANSACTIONID) VALUES (2014-06-26T02:23:09Z, 36840bd430637, Success, 85.0, 11457922, 10.02, USD, X, M, 59106737WV831451U)
Mycode is
$columns = implode(", ",array_keys($result_array));
$escaped_values = array_map('mysql_real_escape_string', array_values($result_array));
$values = implode(", ", $escaped_values);
echo $sql = "INSERT INTO `transaction`($columns) VALUES ($values)";
$res =mysql_query($sql);
what are the changes can i do?
First of all, you should escape column names (not always required):
$cols = join(',', array_map(function($name) {
return '`' . str_replace('`', '``', $name) . '`';
}, array_keys($result_array));
Then, keeping in mind that mysql_real_escape_string() doesn't add quoted enclosures:
$vals = join(',', array_map(function($value) {
return "'" . mysql_real_escape_string($value) . "'";
}, $result_array);
$sql = "INSERT INTO `transaction` ($cols) VALUES ($vals)";
Lastly, using mysql_ functions is deprecated and you should move onto using either PDO or mysqli.
What is meaning of echo $sql here? try this way & you can also escape your string firstly.
foreach($singleRow as $key=>$data) //for multiple rows
{
if(isset($data)){
$dataArray[$key] = is_string($data) ? mysql_real_escape_string($data) : $data;
}
}
$tableName='transaction';
$keys = implode(',',array_keys($dataArray));
$data_values = ("'".implode("','",array_values($dataArray))."'");
$insertSql = "INSERT INTO ".$tableName." ($keys) VALUES ($data_values)";
$res =mysql_query($insertSql );
use mysqli_* and PDO anyway
I have an array like this
$a = array( 'phone' => 111111111, 'image' => "sadasdasd43eadasdad" );
When I do a var-dump I get this ->
{ ["phone"]=> int(111111111) ["image"]=> string(19) "sadasdasd43eadasdad" }
Now I am trying to add this to the DB using the IN statement -
$q = $DBH->prepare("INSERT INTO user :column_string VALUES :value_string");
$q->bindParam(':column_string',implode(',',array_keys($a)));
$q->bindParam(':value_string',implode(',',array_values($a)));
$q->execute();
The problem I am having is that implode return a string. But the 'phone' column is an integer in the database and also the array is storing it as an integer. Hence I am getting the SQL error as my final query look like this --
INSERT INTO user 'phone,image' values '111111111,sadasdasd43eadasdad';
Which is a wrong query. Is there any way around it.
My column names are dynamic based what the user wants to insert. So I cannot use the placeholders like :phone and :image as I may not always get a values for those two columns. Please let me know if there is a way around this. otherwise I will have to define multiple functions each type of update.
Thanks.
Last time I checked, it was not possible to prepare a statement where the affected columns were unknown at preparation time - but that thing seems to work - maybe your database system is more forgiving than those I am using (mainly postgres)
What is clearly wrong is the implode() statement, as each variable should be handled by it self, you also need parenthesis around the field list in the insert statement.
To insert user defined fields, I think you have to do something like this (at least that how I do it);
$fields=array_keys($a); // here you have to trust your field names!
$values=array_values($a);
$fieldlist=implode(',',$fields);
$qs=str_repeat("?,",count($fields)-1);
$sql="insert into user($fieldlist) values(${qs}?)";
$q=$DBH->prepare($sql);
$q->execute($values);
If you cannot trust the field names in $a, you have to do something like
foreach($a as $f=>$v){
if(validfield($f)){
$fields[]=$f;
$values[]=$v;
}
}
Where validfields is a function that you write that tests each fieldname and checks if it is valid (quick and dirty by making an associative array $valfields=array('name'=>1,'email'=>1, 'phone'=>1 ... and then checking for the value of $valfields[$f], or (as I would prefer) by fetching the field names from the server)
SQL query parameters can be used only where you would otherwise put a literal value.
So if you could see yourself putting a quoted string literal, date literal, or numeric literal in that position in the query, you can use a parameter.
You can't use a parameter for a column name, a table name, a lists of values, an SQL keyword, or any other expressions or syntax.
For those cases, you still have to interpolate content into the SQL string, so you have some risk of SQL injection. The way to protect against that is with whitelisting the column names, and rejecting any input that doesn't match the whitelist.
Because all other answers allow SQL injection. For user input you need to filter for allowed field names:
// change this
$fields = array('email', 'name', 'whatever');
$fieldlist = implode(',', $fields);
$values = array_values(array_intersect_key($_POST, array_flip($fields)));
$qs = str_repeat("?,",count($fields)-1) . '?';
$q = $db->prepare("INSERT INTO events ($fieldlist) values($qs)");
$q->execute($values);
I appreciated MortenSickel's answer, but I wanted to use named parameters to be on the safe side:
$keys = array_keys($a);
$sql = "INSERT INTO user (".implode(", ",$keys).") \n";
$sql .= "VALUES ( :".implode(", :",$keys).")";
$q = $this->dbConnection->prepare($sql);
return $q->execute($a);
You actually can have the :phone and :image fields bound with null values in advance. The structure of the table is fixed anyway and you probably should got that way.
But the answer to your question might look like this:
$keys = ':' . implode(', :', array_keys($array));
$values = str_repeat('?, ', count($array)-1) . '?';
$i = 1;
$q = $DBH->prepare("INSERT INTO user ($keys) VALUES ($values)");
foreach($array as $value)
$q->bindParam($i++, $value, PDO::PARAM_STR, mb_strlen($value));
I know this question has be answered a long time ago, but I found it today and have a little contribution in addition to the answer of #MortenSickel.
The class below will allow you to insert or update an associative array to your database table. For more information about MySQL PDO please visit: http://php.net/manual/en/book.pdo.php
<?php
class dbConnection
{
protected $dbConnection;
function __construct($dbSettings) {
$this->openDatabase($dbSettings);
}
function openDatabase($dbSettings) {
$dsn = 'mysql:host='.$dbSettings['host'].';dbname='.$dbSettings['name'];
$this->dbConnection = new PDO($dsn, $dbSettings['username'], $dbSettings['password']);
$this->dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
function insertArray($table, $array) {
$fields=array_keys($array);
$values=array_values($array);
$fieldlist=implode(',', $fields);
$qs=str_repeat("?,",count($fields)-1);
$sql="INSERT INTO `".$table."` (".$fieldlist.") VALUES (${qs}?)";
$q = $this->dbConnection->prepare($sql);
return $q->execute($values);
}
function updateArray($table, $id, $array) {
$fields=array_keys($array);
$values=array_values($array);
$fieldlist=implode(',', $fields);
$qs=str_repeat("?,",count($fields)-1);
$firstfield = true;
$sql = "UPDATE `".$table."` SET";
for ($i = 0; $i < count($fields); $i++) {
if(!$firstfield) {
$sql .= ", ";
}
$sql .= " ".$fields[$i]."=?";
$firstfield = false;
}
$sql .= " WHERE `id` =?";
$sth = $this->dbConnection->prepare($sql);
$values[] = $id;
return $sth->execute($values);
}
}
?>
dbConnection class usage:
<?php
$dbSettings['host'] = 'localhost';
$dbSettings['name'] = 'databasename';
$dbSettings['username'] = 'username';
$dbSettings['password'] = 'password';
$dbh = new dbConnection( $dbSettings );
$a = array( 'phone' => 111111111, 'image' => "sadasdasd43eadasdad" );
$dbh->insertArray('user', $a);
// This will asume your table has a 'id' column, id: 1 will be updated in the example below:
$dbh->updateArray('user', 1, $a);
?>
public function insert($data = [] , $table = ''){
$keys = array_keys($data);
$fields = implode(',',$keys);
$pre_fields = ':'.implode(', :',$keys);
$query = parent::prepare("INSERT INTO $table($fields) VALUES($pre_fields) ");
return $query->execute($data);
}