BindParam for inserting multiple values - php

Let's say I have value for user,form,and ownerID. The value for user stays the same however ownerID might vary from time to time.
for example:
$user = "Farhana"; // fix value
$form = "Registration"; // fix value
$ownerID = array("23","50","33"); // item in array not fix, may have many ownerID
then I want to insert multiple values with single sql statement like this.
INSERT INTO messages (user,ownerID,form) VALUES ("Farhana","23","Registration"),("Farhana","50","Registration"),("Farhana","33","Registration");
so I have come out with foreach solution but I'm not sure this is correct or not.
// prepare
$stmt = $this->conn->prepare("INSERT INTO messages (user,ownerID,form) VALUES (?,?,?)");
// bind param
foreach ($ownerID as $ID){
$stmt->bind_param("sss",$user,$ID,$form);
$stmt->execute();
}

It's not really important, but just for sake of clarity bind_param have to be called only once.
$stmt = $this->conn->prepare("INSERT INTO messages (user,ownerID,form) VALUES (?,?,?)");
$stmt->bind_param("sss",$user,$ID,$form);
foreach ($ownerID as $ID){
$stmt->execute();
}

Related

Pass an SQL query to php PDO function and execute [duplicate]

Currently Im trying to create a PDO class where I will have a method to run a query like INSERT, UPDATE, or DELETE.
For examaple this is my method for a SELECT
public function getPreparedQuery($sql){
$stmt = $this->dbc->prepare($sql);
$stmt->execute([5]);
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if(!$arr) exit('No rows');
$stmt = null;
return $arr;
}
And i Simply call it like this:
$stmt = $database->getPreparedQuery($sql2);
var_export($stmt);
And so far I know that a runQuery should work something similar to this:
Insert Example without using a method:
$idRol = "6";
$nomRol = "test6";
$stmt = $database->dbc->prepare("insert into roles (idRol, NomRol) values (?, ?)");
$stmt->execute(array($idRol,$nomRol));
$stmt = null;
But I want to make it into an universal method where i simply can pass the sql sentence, something like this:
$database->runQuery($query);
but the query can happen to be
$query = "INSERT INTO roles (idRol, NomRol) VALUES ('4','test')";
or
$query = "INSERT INTO movies (movName, movLength, movArg) VALUES ('name1','15','movie about...')";
So how do I slice the arg $query so I can get all the variables that are being used in order to make an universal runQuery?
Because I can imagine that my method should be something like this
runQuery([$var1 , $var2, $var3....(there can be more)] , [$var1value, $var2value, $var3value...(there can be more)]){
$stmt = $database->dbc->prepare("insert into movies($var1 , $var2, $var3....(there can be more)) values (?, ? , ? (those are the values and there ca be more than 3)"); //how do i get those "?" value and amount of them, and the name of the table fields [movName, movLength, movArg can be variable depending of the sentence]?
$stmt->execute(array($var1,$var2, $var3, ...)); //this is wrong , i dont know how to execute it
$stmt = null;
}
You need to add a second parameter to your function. Simply an array where all those variables would go. An array by definition can have an arbitrary number of elements, which solves your problem exactly:
public function runQuery($sql, $parameters = []) {
$stmt = $this->dbc->prepare($sql);
$stmt->execute($parameters);
return $stmt;
}
this simple function will run ANY query. You can see the usage example in my article dedicated to PDO helper functions:
// getting the number of rows in the table
$count = $db->runQuery("SELECT count(*) FROM users")->fetchColumn();
// the user data based on email
$user = $db->runQuery("SELECT * FROM users WHERE email=?", [$email])->fetch();
// getting many rows from the table
$data = $db->runQuery("SELECT * FROM users WHERE salary > ?", [$salary])->fetchAll();
// getting the number of affected rows from DELETE/UPDATE/INSERT
$deleted = $db->runQuery("DELETE FROM users WHERE id=?", [$id])->rowCount();
// insert
$db->runQuery("INSERT INTO users VALUES (null, ?,?,?)", [$name, $email, $password]);
// named placeholders are also welcome though I find them a bit too verbose
$db->runQuery("UPDATE users SET name=:name WHERE id=:id", ['id'=>$id, 'name'=>$name]);
// using a sophisticated fetch mode, indexing the returned array by id
$indexed = $db->runQuery("SELECT id, name FROM users")->fetchAll(PDO::FETCH_KEY_PAIR);
As you can see, now your function can be used with any query with any number of parameters

How to make a PDO class method for inserting/updating/deleting with an unknown number of parameters in the arg

Currently Im trying to create a PDO class where I will have a method to run a query like INSERT, UPDATE, or DELETE.
For examaple this is my method for a SELECT
public function getPreparedQuery($sql){
$stmt = $this->dbc->prepare($sql);
$stmt->execute([5]);
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if(!$arr) exit('No rows');
$stmt = null;
return $arr;
}
And i Simply call it like this:
$stmt = $database->getPreparedQuery($sql2);
var_export($stmt);
And so far I know that a runQuery should work something similar to this:
Insert Example without using a method:
$idRol = "6";
$nomRol = "test6";
$stmt = $database->dbc->prepare("insert into roles (idRol, NomRol) values (?, ?)");
$stmt->execute(array($idRol,$nomRol));
$stmt = null;
But I want to make it into an universal method where i simply can pass the sql sentence, something like this:
$database->runQuery($query);
but the query can happen to be
$query = "INSERT INTO roles (idRol, NomRol) VALUES ('4','test')";
or
$query = "INSERT INTO movies (movName, movLength, movArg) VALUES ('name1','15','movie about...')";
So how do I slice the arg $query so I can get all the variables that are being used in order to make an universal runQuery?
Because I can imagine that my method should be something like this
runQuery([$var1 , $var2, $var3....(there can be more)] , [$var1value, $var2value, $var3value...(there can be more)]){
$stmt = $database->dbc->prepare("insert into movies($var1 , $var2, $var3....(there can be more)) values (?, ? , ? (those are the values and there ca be more than 3)"); //how do i get those "?" value and amount of them, and the name of the table fields [movName, movLength, movArg can be variable depending of the sentence]?
$stmt->execute(array($var1,$var2, $var3, ...)); //this is wrong , i dont know how to execute it
$stmt = null;
}
You need to add a second parameter to your function. Simply an array where all those variables would go. An array by definition can have an arbitrary number of elements, which solves your problem exactly:
public function runQuery($sql, $parameters = []) {
$stmt = $this->dbc->prepare($sql);
$stmt->execute($parameters);
return $stmt;
}
this simple function will run ANY query. You can see the usage example in my article dedicated to PDO helper functions:
// getting the number of rows in the table
$count = $db->runQuery("SELECT count(*) FROM users")->fetchColumn();
// the user data based on email
$user = $db->runQuery("SELECT * FROM users WHERE email=?", [$email])->fetch();
// getting many rows from the table
$data = $db->runQuery("SELECT * FROM users WHERE salary > ?", [$salary])->fetchAll();
// getting the number of affected rows from DELETE/UPDATE/INSERT
$deleted = $db->runQuery("DELETE FROM users WHERE id=?", [$id])->rowCount();
// insert
$db->runQuery("INSERT INTO users VALUES (null, ?,?,?)", [$name, $email, $password]);
// named placeholders are also welcome though I find them a bit too verbose
$db->runQuery("UPDATE users SET name=:name WHERE id=:id", ['id'=>$id, 'name'=>$name]);
// using a sophisticated fetch mode, indexing the returned array by id
$indexed = $db->runQuery("SELECT id, name FROM users")->fetchAll(PDO::FETCH_KEY_PAIR);
As you can see, now your function can be used with any query with any number of parameters

get the id of the last inserted row in mysql

I have looked everywhere and keep getting different answers and incorrect code. All I want to do is after I have added a field to my database in MySQL is to get the user_id of the field that has just been created. I just cannot seem to do it?
I am using this to input the field and thanks for any help. It has a auto_increment value of user_id which is what I need to get.
mysqli_query($con,"INSERT INTO users_accounts (business, email_uniq)
VALUES ('$business', '$email_uniq')");
use this after insert query
$last_row = mysqli_insert_id($con);
You can return the primary key of the last row inserted with
$last_id = mysqli_insert_id($con);
You can find more information here: http://php.net/manual/en/mysqli.insert-id.php
After executing the query, you can use mysqli::$insert_id value or mysqli_insert_id function to retrieve the last generated id, like this:
mysqli_query($con,"INSERT INTO users_accounts (business, email_uniq) VALUES ('$business', '$email_uniq')");
$insert_id = mysqli_insert_id($con);
or using the object functions:
$con->query("INSERT INTO users_accounts (business, email_uniq) VALUES ('$business', '$email_uniq')");
$insert_id = $con->insert_id;
edit: Not related, but definitly important!
If the values for either of these parameters $business or $email_uniq are user supplied, it is highly recommended to make sure they are filtered properly. The easiest way is by using a prepared statement for security (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Here is your code using prepared statements:
$stmt = $con->prepare("INSERT INTO users_accounts (business, email_uniq) VALUES (?,?)");
$stmt->bind_param("ss", $business, $email_uniq);
$stmt->execute();
$insert_id = $con->insert_id;

PDO multiple inserts only insert last value from multiple checkboxes

I am trying to insert data into my db using PDO. I have been successful until now but the following error has happened to me and I do not know the reason.
My goal is to insert data into three different tables at once ussing transactions. In the last two tables the records come from multiple checkboxes and store them as an array is not an option. I have been successful in storing the multiple values from the checkboxes when I only use first two queries but as soon as I add the third query in the transaction only the last value from the while is included into the database.
It's very strange because when I save the data into the user and language table using the while it works fine including all data but when I added the third query. The program stops working as I intended and the data base only receive the last record for both language and education table.
I get the following data from a html form and I send it to the class:
if($_POST){
// set values to object properties
$user->firstname=$_POST['firstname'];
$user->lastname=$_POST['lastname'];
$user->user_id=$_SESSION['user_id'];
// Data for the language table, second query in class function
while(list($key,$value) = each($_POST['language']))
{$user->language=$value;}
while(list($key,$value) = each($_POST['level']))
{$user->level=$value;}
// Data for the education table, third query in class function
while(list($key,$value) = each($_POST['studies']))
{$user->studies=$value;}
while(list($key,$value) = each($_POST['insti']))
{$lawyer->institution=$value;}
while(list($key,$value) = each($_POST['from']))
{$user->from_start=$value;}
while(list($key,$value) = each($_POST['to']))
{$user->to_end=$value;}
// create the user
if($user->registeruser()){
echo "<div class=\"alert alert-info\">";
echo "Registration completed, thank you. In the following 24 hours a member of our team will contact you. ";
echo "</div>";
}else{
echo "<div class=\"alert alert-danger\" role=\"alert\">Unable to register. Please try again.</div>";
}
}
The class function is written as follow:
function registeruser(){
try {
$this->conn->beginTransaction();
$query = "UPDATE
users
SET
firstname = :firstname,
lastname = :lastname,
WHERE
id = :id";
// prepare query statement
$stmt = $this->conn->prepare($query);
// bind variable values
$stmt->bindParam(':firstname', $this->firstname);
$stmt->bindParam(':lastname', $this->lastname);
$stmt->bindParam(':id', $this->user_id);
// execute the query
$stmt->execute();
$query = 'INSERT INTO language (user_id,language,level) VALUES (?,?,?)';
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $this->user_id);
$stmt->bindParam(2, $this->language);
$stmt->bindParam(3, $this->level);
$stmt->execute();
$query = 'INSERT INTO education (user_id,studies,school,from_start,to_end) VALUES (?,?,?,?,?)';
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $this->user_id);
$stmt->bindParam(2, $this->studies);
$stmt->bindParam(3, $this->institution);
$stmt->bindParam(4, $this->from_start);
$stmt->bindParam(5, $this->to_end);
$stmt->execute();
$this->conn->commit();
return true;
} catch (Exception $e) {
$stmt->rollBack();
return false;
}
}
Thank you in advance.
PD: There is not error from db or php code. The problem is that the second and third query in the transaction are not inserting the multiple values from checkboxes into the DB, only the last. When I only include two queries into the transaction all values from the checkboxes are included the different table.

mySQLi Prepared Statement Select with Escape Characters

I am trying to select from a mySQL table using prepared statements. The select critera is user form input, so I am binding this variable and using prepared statements. Below is the code:
$sql_query = "SELECT first_name_id from first_names WHERE first_name = ?";
$stmt = $_SESSION['mysqli']->prepare($sql_query);
$stmt->bind_param('s', $_SESSION['first_name']);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == '1') {
$stmt->bind_result($_SESSION['first_name_id']);
$stmt->fetch();
} else {
$stmt->close();
$sql_query = "INSERT INTO first_names (first_name) VALUES (?)";
$stmt = $_SESSION['mysqli']->prepare($sql_query);
$stmt->bind_param('s', $_SESSION['first_name']);
$stmt->execute();
$_SESSION['first_name_id'] = $_SESSION['mysqli']->insert_id;
}
$stmt->close();
Obviously my code is just determining whether or not the first_name already exists in the first_names table. If it does, it returns the corresponding ID (first_name_id). Otherwise, the code inserts the new first_name into the first_names table and gets the insert_id.
The problem is when a user enters a name with an escape character ('Henry's). Not really likely with first names but certainly employers. When this occurs, the code does not execute (no select or insert activity in the log files). So it seems like mySQL is ignoring the code due to an escape character in the variable.
How can I fix this issue? Is my code above efficient and correct for the task?
Issue #2. The code then continues with another insert or update, as shown in the code below:
if (empty($_SESSION['personal_id'])) {
$sql_query = "INSERT INTO personal_info (first_name_id, start_timestamp) VALUES (?, NOW())";
} else {
$sql_query = "UPDATE personal_info SET first_name_id = ? WHERE personal_info = '$_SESSION[personal_id]'";
}
$stmt = $_SESSION['mysqli']->prepare($sql_query);
$stmt->bind_param('i', $_SESSION['first_name_id']);
$stmt->execute();
if (empty($_SESSION['personal_id'])) {
$_SESSION['personal_id'] = $_SESSION['mysqli']->insert_id;
}
$stmt->close();
The issue with the code above is that I cannot get it to work at all. I am not sure if there is some conflict with the first part of the script, but I have tried everything to get it to work. There are no PHP errors and there are no inserts or updates showing in the mySQL log files from this code. It appears that the bind_param line in the code may be where the script is dying...
Any help would be very much appreciated.
you should validate/escape user input before sending it to the db.
checkout this mysql-real-escape-string()

Categories