I tried to find another question with the answer to this but I've had no luck. My question is basically...will this work?
$insert_tweets = "INSERT INTO tweets (
'id',
'created_at',
'from_user_id',
'profile_image',
'from_user',
'from_user_name',
'text'
) VALUES (
{$user_data[$i]["id"]},
{$user_data[$i]["created_at"]},
{$user_data[$i]["from_user_id"]},
{$user_data[$i]["profile_image"]},
{$user_data[$i]["from_user"]},
{$user_data[$i]["from_user_name"]},
{$user_data[$i]["text"]}
)"
for($i=0;$i<count($user_data);$i++){
mysqli_query($mysqli,$insert_tweets);
}
$user_data is a multi-dimensional array, the first level of which is numeric, the subsequent level is associative.
Also, what would be the best way to "database prepare"/sanitize the associative array variables prior to insertion? I don't anticipate any malicious data but it is always possible.
for($i=0;$i<count($user_data);$i++){
$insert_tweets = "INSERT INTO tweets ('id','created_at','from_user_id','profile_image','from_user','from_user_name','text') VALUES ({$user_data[$i]["id"]},{$user_data[$i]["created_at"]},{$user_data[$i]["from_user_id"]},{$user_data[$i]["profile_image"]},{$user_data[$i]["from_user"]},{$user_data[$i]["from_user_name"]},{$user_data[$i]["text"]})";
mysqli_query($mysqli,$insert_tweets);
}
This should work
Yes, it will work, but the best way to do this would be to use PDO.
You can create nameless parameters in your prepare statement and then just pass in a array to bind values to those params.
$data = array('val1', 'val2');
$query = $db->prepare("INSERT INTO table (col1, col2) VALUES (? , ?)");
$query->execute($data);
PDO will escape the input values for you.
Here's a tutorial on PDO to get you started
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
Here is my suggestion on sanitizing your array:
What i do is create a basic function for sanitizing data:
function array_sanitize(&$item){
$item = mysql_real_escape_string($item);
}
Then you can use the array_walk() to sanitize your array with your new function. (php manual refrence)
and sanitize by passing in your array like this:
array_walk($user_data, 'array_sanitize');
Related
Before you duplicate your question, I read all answers that it's has a relation with my question. I'm trying to insert data with associative array for example
<?php
$data = array(
'fname'=>'joe',
'lname'=>'sina'
);
foreach ($data as $key=>$value) {
}
?>
I want to display data like this
/*insert into tblname($key)values($value);
finally the query will appear correctly format */
insert into tblname('fname','lname') values('joe','sina');
You don't need to use foreach here. If you just prepare and bind the query, you can pass $data to the execute() and get the keys by implode() on the keys.
$data = array(
'fname'=>'joe',
'lname'=>'sina'
);
$stmt = $pdo->prepare("INSERT INTO tblname (".implode(', ', array_keys($data)).") VALUES (:".implode(', :', array_keys($data)).")");
$stmt->execute($data);
The keys in the array must match the placeholders in the query (the ones with a colon in front of it). You also had a syntax error in the query, as columns cannot be quoted by singlequotes.
I have an array of variables:
$values = array($a,$b,$c);
i want to pass this array through this function:
function db_insert($table, $attributes, $values)//insert into the database
{
// $values and takes an array of variables. $attributes is a string "att1, att2,...."
$result = mysql_query("INSERT INTO ' '".$table."' ( '".$attributes."' ) VALUES ( '".implode("','", $values)."' )");
return $result;
}
I pass it like this but it doesn't work:
db_insert("table","a,b,c",$values);
There is no errors but the record is not stored into the database. What is the problem?
You probably want this:
$result = mysql_query("INSERT INTO $table ($attributes) VALUES ('".implode("','", $values)."')");
As a side note you should switch to using mysqli_ functions or PDO instead of mysql_, see why here. You should also read a bit on placeholders and how to use them in your queries.
First of all, I apologize if this is answered somewhere else, but I couldn't find anything.
I have problems with the following code:
function register_user ($register_data) {
global $db;
array_walk ($register_data, 'array_sanitize');
$register_data ['password'] = md5 ($register_data ['password']);
$fields = '`' . implode ('`, `', array_keys ($register_data)) . '`';
$data = '\'' . implode ('\', \'', $register_data) . '\'';
$query = $db -> prepare ("INSERT INTO `users` (:fields) VALUES (:data)");
$query -> bindParam (':fields', $fields);
$query -> bindParam (':data', $data);
$query -> execute ();
}
The problem is that this is executed correctly but the query is not ran and the row is not inserted in the database.
Now, if I just do this:
$query = $db -> prepare ("INSERT INTO `users` ($fields) VALUES ($data)");
//$query -> bindParam (':fields', $fields);
//$query -> bindParam (':data', $data);
$query -> execute ();
everything works like a charm, so I am guessing the problem is with how I am passing data to the placeholders.
Can someone please explain to me why this is not working? I'd like to understand it properly in the first place.
Thanks in advance for any help.
There are two different use cases that could be described as Passing an imploded array to a query placeholder. One is using prepared statements with IN() clause in SQL. this case is already fully covered in this answer.
Another use case is an insert helper function, like one featured in your question. I've got an article that explains how to create an SQL injection proof insert helper function for PDO_MYSQL.
Given such a function is not only adding data values to the query but also table and column names, a prepared statement won't be enough to protect from SQL injection. Hence, such a function will need a helper function of its own, to protect table and field named. Here is one for MySQL:
function escape_mysql_identifier($field){
return "`".str_replace("`", "``", $field)."`";
}
And now we can finally have a function that accepts a table name and an array with data and runs a prepared INSERT query against a database:
function prepared_insert($pdo, $table, $data) {
$keys = array_keys($data);
$keys = array_map('escape_mysql_identifier', $keys);
$fields = implode(",", $keys);
$table = escape_mysql_identifier($table);
$placeholders = str_repeat('?,', count($keys) - 1) . '?';
$sql = "INSERT INTO $table ($fields) VALUES ($placeholders)";
$pdo->prepare($sql)->execute(array_values($data));
}
that can be used like this:
prepared_insert($pdo, 'users', ['name' => $name, 'password' => $hashed_password]);
the full explanation can be found in the article linked above, but in brief, we are creating a list of column names from the input array keys and a list of comma separated placeholders for the SQL VALUES() clause. And finally we are sending the input array values into PDO's execute(). Safe, convenient and concise.
Does anyone have best practices when inserting an array into a database? I've used foreach loops with success in the past, as well as various array functions. Is there a better way?
Here is a sample code:
public function InsertRequests($id) {
$db = Database::getHandler();
$selected_requests = $this->GetRequests($this->allrequests);
foreach($selected_requests as $requestid) {
$sql = "INSERT INTO requests (userid,requestid,date) VALUES (?,?,NOW())";
$stmt = $db->prepare($sql);
$stmt->bindParam(1,$id,PDO::PARAM_STR);
$stmt->bindParam(2,$requestid,PDO::PARAM_STR);
$stmt->execute();
}
return true;
}
}
You can insert multiple records with a single query like this:
INSERT INTO TABLENAME ( fieldOne, fieldTwo, fieldThree ) VALUES
( 'Jack', 'Nickholson', 'M' ),
( 'Audrey', 'Hepburn', 'F' ),
( 'Salvador', 'Dali', 'M' )
...
So, prepare your INSERT syntax iterating over your data array in a regular loop or using custom query builder than execute it once. Better practice is using an ORM library like #Karoly's said.
Thanks for looking. All helpful answers/comments are up voted.
In php, you can use NOW() like this:
mysql_query("INSERT INTO tablename (id, value, time_created)
VALUES ('{$id}', '{$value}', NOW())");
How can I do the same thing in PDO. When I bind like this, I get an error:
$stmt->bindParam(':time_added', NOW(), PDO::PARAM_STR);
Is it the PDO:PARAM_STR?
Because nobody has explicitly answered the question, I'll add the correct answer for the sake of completeness.
$stmt = $pdoDb->prepare('INSERT INTO tablename (id, value, time_created) VALUES (:id, :value, NOW())');
// either bind each parameter explicitly
$stmt->bindParam(':id', $id); // PDOStatement::bindValue() is also possibly
$stmt->bindParam(':value', $value);
$stmt->execute();
// or bind when executing the statement
$stmt->execute(array(
':id' => $id,
':value' => $value
));
Presuming your PDO statement is correct you could do something like this:
$date = date('Y-m-d H:i:s');
$stmt->bindParam(':time_added', $date, PDO::PARAM_STR);
None of the answers solve the question as I see it!
So there are some of my findings:
there is NO WAY how to force PDO to pass MySQL function call as a query value - so there is no way to do simple wrapper that will be able to use NOW() or any other function as passed values. Every time you need something like that, you need manually change the query, so the function call is part of the query string. :-(
I'm using function that tests given values for MySQL function I am using and modifies the query itself, but it is not a good solution to my opinion... :-}
This might be useful to some of you, maybe not. I was confronted with the same problem as Ollie Saunders was. I'm pretty new to php/mysql, and most of all PDO. I was able to solve the problem with the following:
$active = 0;
$id = NULL;
$query = "INSERT
INTO tbl_user(ID_user, firstname, lastname, email, password, active, create_date)
VALUES (?,?,?,?,?,?,NOW())";
if($stmt=$this->conn->prepare($query)) {
$stmt->bind_param('issssi', $id, $firstname, $lastname, $email, $password, $active);
$stmt->execute();
}
and guess what it works! Hope to have helped here. Any comments are welcome. Try it and tell me if it worked for you, or if you have any additions.
To answer Elmo's question, you can create a PDO wrapper that allows for SQL functions like NOW(). You just need to pass an additional argument with the columns that you want to use SQL functions for. Here's mine:
function pInsertFunc($action, $table, $values, $sqlfunctions)
{
global $pdb;
// There's no way to pass an SQL function like "NOW()" as a PDO parameter,
// so this function builds the query string with those functions. $values
// and $sqlfunctions should be key => value arrays, with column names
// as keys. The $values values will be passed in as parameters, and the
// $sqlfunction values will be made part of the query string.
$value_columns = array_keys($values);
$sqlfunc_columns = array_keys($sqlfunctions);
$columns = array_merge($value_columns, $sqlfunc_columns);
// Only $values become ':paramname' PDO parameters.
$value_parameters = array_map(function($col) {return (':' . $col);}, $value_columns);
// SQL functions go straight in as strings.
$sqlfunc_parameters = array_values($sqlfunctions);
$parameters = array_merge($value_parameters, $sqlfunc_parameters);
$column_list = join(', ', $columns);
$parameter_list = join(', ', $parameters);
$query = "$action $table ($column_list) VALUES ($parameter_list)";
$stmt = $pdb->prepare($query);
$stmt->execute($values);
}
Use it like this:
$values = array(
'ID' => NULL,
'name' => $username,
'address' => $address,
);
$sqlfuncs = array(
'date' => 'NOW()',
);
pInsertFunc("INSERT INTO", "addresses", $values, $sqlfuncs);
The query string that results looks like this:
INSERT INTO addresses (ID, name, address, date) VALUES (:ID, :name, :address, NOW())
other than NOW() i also utilize the "timestamp" type column and set its default to CURRENT_TIMESTAMP .. so i just pass nothing for that field and time is automatically set. maybe not exactly what ur looking for.