Mysqli INSERT with $_POST - php

I have been ripping my hair for days over this problem so any helpful advice would be appreciated. Calling the following function returns nothing. The POST values are set (They print with echo) and the database let me update and extract with other functions. What am i missing?
Oh yea, all the values are strings.
$stmt = $db->prepare("INSERT INTO content_page (name, layout, page_id) VALUES (?,?,?)");
$stmt->bind_param("sss", $_POST['name'], $_POST['layout'], $_POST['page_id']);
$stmt->execute();
$stmt->close();

At glance, there is nothing wrong with this code (in case you are indeed using mysqli). So, the only way to get to know what is going wrong is to get the error message.
Add this line before connect
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
and make sure you can see PHP errors

Try this
$sql = "INSERT INTO content_page (name, layout, page_id) VALUES (?,?,?)";
if (!$stmt = $db->prepare($sql)) {
die($db->error);
}
$stmt->bind_param("ssi", $_POST['name'], $_POST['layout'], $_POST['page_id']);
if (!$stmt->execute()) {
die($stmt->error);
}
$stmt->close();
Or, if, as you said, all your values are strings (given, they are as well defined as varchars/something similar in your database), you can still bind_param("sss"...

Aren't page_id's integers ? Since the asker first tagged the question as PDO, here is the PDO version :
$stmt = $db->prepare("INSERT INTO content_page (name, layout, page_id) VALUES (:name,:layout,:pid)");
$sth->bindParam(':name', $_POST['name'], PDO::PARAM_STR);
$sth->bindParam(':layout', $_POST['layout'], PDO::PARAM_STR);
$sth->bindParam(':pid', $_POST['page_id'], PDO::PARAM_INT);
$stmt->execute();
Or (MySQLi):
$stmt = $db->prepare("INSERT INTO content_page (name, layout, page_id) VALUES (?,?,?)");
$stmt->bind_param("ssi", $_POST['name'], $_POST['layout'], $_POST['page_id']);
$stmt->execute();
Or (PDO) :
$stmt = $db->prepare("INSERT INTO content_page (name, layout, page_id) VALUES (?,?,?)");
$stmt->execute(array($_POST['name'], $_POST['layout'], $_POST['page_id']));

Here you are:
$name = $_POST['layout'];
$layout = $_POST['layout'];
$page_id= $_POST['page_id'];
$stmt = $db->prepare("INSERT INTO content_page (name, layout, page_id) VALUES ('".$name."','".$layout."','".$page_id."')");

Related

How to use PHP prepare with zillions of fields of different types

I am inserting data that has VARCHAR, TIMESTAMP and DECIMAL kinds using prepare.
The data is already in the format needed by mySQL.
My problem is this. Suppose I had only 2 items to insert. I would do like this:
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param("si", $_POST['name'], $_POST['age']);
My problem is the bind part. How do I do the bind when I have to insert 40 columns at once?
I can deal with the prepare part by doing this:
$sql = "INSERT INTO customers ($columns) VALUES ($values)";
$stmt = $mysqli->prepare($sql);
But the next line will result in a ridiculous long line, impossible to understand and very easy to go wrong.
$stmt->bind_param("ssssiidisisssiidiisssidiisidi", ....);
I don't see how I could build that in a loop for example.
How do I do that?
You can pass an array to the mysqli_stmt::bind_param() function as variable arguments with the ... syntax, introduced in PHP 5.6.
$params = ['name', 42];
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
You don't really need to set the data type individually for each column. You can treat them all as 's'.
I know you're asking about mysqli, but I'll just point out that this is easier with PDO:
$params = ['name', 42];
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute($params);

$mysqli->prepare with SQL Transactions

I am pretty new to SQL Transactions and tried to execute following statement which did unfortunately not work...
$stmt = $mysqli->prepare("
BEGIN;
INSERT INTO groups (group_name, group_desc, user_id_fk) VALUES ("'.$groupName.'","'.$groupDesc.'","'.$user_id.'");
INSERT INTO group_users (group_id_fk, user_id_fk) VALUES (LAST_INSERT_ID(), "'.$username.'");
COMMIT;
") or trigger_error($mysqli->error, E_USER_ERROR);
$stmt->execute();
$stmt->close();
Is this even possible what I am trying here or is it completely wrong?
I appreciate every response, thank you!
You are using prepare() wrong way. There is absolutely no point in using prepare() if you are adding variables directly in the query.
This is how your queries have to be executed:
$mysqli->query("BEGIN");
$sql = "INSERT INTO groups (group_name, group_desc, user_id_fk) VALUES (?,?,?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ssi",$groupName,$groupDesc,$user_id);
$stmt->execute();
$sql = "INSERT INTO group_users (group_id_fk, user_id_fk) VALUES (LAST_INSERT_ID(), ?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s",$username);
$stmt->execute();
$mysqli->query("COMMIT");

If statement on PHP (inserting data)

I have to register a costumer and/or a manager into the database. I just have one form for the information, the only difference is the ID number (valid for managers). The costumers should leave this form blank. I was trying to save the data just using an if statement (If it is blank, save the information in costumer table. If it is not, save in manager). I have not seen this on my classes so I am not sure if it is possible.
Is it possible to use an if statement to insert data? What I mean is, I have two different tables but just one form (one of the forms will make the difference for which table the data will be saved.
The data in the manager table is ok, but when I try to insert data into costumer it is not working. I am not sure that I can use this.
if($_SESSION['id'] != null){
$sql = "INSERT INTO manager (id,magname,maglname,maguser,magpass) VALUES (?, ?, ?, ?, ?);";
$sth = $DBH->prepare($sql);
$sth->bindParam(1, $_SESSION['id'], PDO::PARAM_INT);
$sth->bindParam(2, $_SESSION['firstname'], PDO::PARAM_INT);
$sth->bindParam(3, $_SESSION['secondname'], PDO::PARAM_INT);
$sth->bindParam(4, $_SESSION['username'], PDO::PARAM_INT);
$sth->bindParam(5, $_SESSION['password'], PDO::PARAM_INT);
$sth->execute();
}
if(empty($_SESSION['id']){
$sql = "INSERT INTO costumer (fisrtname,lastname,username,password) VALUES (?, ?, ?, ?);";
$sth = $DBH->prepare($sql);
$sth->bindParam(1, $_SESSION['firstname'], PDO::PARAM_INT);
$sth->bindParam(2, $_SESSION['lastname'], PDO::PARAM_INT);
$sth->bindParam(3, $_SESSION['username'], PDO::PARAM_INT);
$sth->bindParam(4, $_SESSION['password'], PDO::PARAM_INT);
$sth->execute();
}
you can do it directly through following code
if(isset($_SESSION['id']))
$sql = "INSERT INTO `manager`..."
else
$sql = "INSERT INTO `customer`..."
or something like this
if(!empty($_SESSION['id']))
{ $sql = "INSERT INTO `manager`..."}
else
{ $sql = "INSERT INTO `customer`..."}

PDO prepared statement and bindValues from an array

I have the following block of code in a PDO statement:
$stmt = $db->prepare("INSERT INTO first_page_data (title, first_name, surname, phone, email, add1, add2, add3, add4, add5) VALUES(?,?,?,?,?,?,?,?,?,?)");
$stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['first_name'], PDO::PARAM_STR);
$stmt->bindValue(3, $_POST['surname'], PDO::PARAM_STR);
$stmt->bindValue(4, $_POST['phone'], PDO::PARAM_INT);
$stmt->bindValue(5, $_POST['email'], PDO::PARAM_STR);
$stmt->bindValue(6, $_POST['add1'], PDO::PARAM_STR);
$stmt->bindValue(7, $_POST['add2'], PDO::PARAM_STR);
$stmt->bindValue(8, $_POST['add3'], PDO::PARAM_STR);
$stmt->bindValue(9, $_POST['add4'], PDO::PARAM_STR);
$stmt->bindValue(10, $_POST['add5'], PDO::PARAM_STR);
$stmt->execute();
$_SESSION['buyer_email'] = $_POST['email'];
Can these parameters (title, first_name, etc) be put into the bindValues using an array and a for each loop? I can get the prepare statement working by just having an array containing the titles but cant seem to get the variable names inside the $_POST values. It would save quite a few lines of code, but I cant quite get there!
The following is the array im using in the prepared statement that I want to use in the bind value loop:
$first = array('title','first_name','surname','phone','email','add1','add2','add3','add4','add5');
Just simply loop over $first and call bindValue for each one.
foreach($first as $key=>$val){
$stmt->bindValue($key+1, $_POST[$val], PDO::PARAM_STR);
}
Or you can use it like this:
$stmt = $db->prepare("INSERT INTO first_page_data (title, first_name, surname, phone, email, add1, add2, add3, add4, add5) VALUES(?,?,?,?,?,?,?,?,?,?)");
$stmt->execute($array);
The array would be like:
$array = array($_POST['title'],$_POST['first_name']);
or if you have the correct order already just
$array = $_POST;

Insert into 2 tables from 1 form. Mysql Transaction?

The user will create an article and submit an image with it.
+The article will go to the articles table.
+The image will go to images table (so that it can be used in other areas of the site).
It has been suggested I use TRANSACTIONS but I am getting errors.
$sql ='BEGIN INSERT INTO articles(article_title, article_text, article_date)
VALUES (?, ?, NOW())
INSERT INTO images(article_id, image_caption)
VALUES(LAST_INSERT_ID(),?);
COMMIT';
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param('sss', $_POST['article_name'], $_POST['description'], $_POST['image_caption']);
$OK = $stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
$stmt->free_result();
} else{
echo "Failure- article not uploaded";
}
$mysqli->query("START TRANSACTION");
$stmt = $mysqli->prepare('INSERT INTO articles(article_title, article_text, article_date) VALUES (?, ?, NOW())');
$stmt->bind_param('ss', $_POST['article_name'], $_POST['description']);
$stmt->execute();
$stmt = $mysqli->prepare('INSERT INTO images (article_id, image_caption) VALUES(LAST_INSERT_ID(),?)');
$stmt->bind_param('s', $_POST['image_caption']);
$stmt->execute();
$stmt->close();
$mysqli->query("COMMIT");
It looks like you are using PDO (nice!). With PDO, you can get your transactions in an easy way with beginTransaction() and commit()
Your code would look like:
$pdo->beginTransaction();
// .. fire your 'normal' queries.
// .. and yet some more queries
$pdo->commit();
Then, I'd personally write separate INSERT queries in just two separate statements. More readable in my opinion.
Example:
$pdo->beginTransaction();
$first = $pdo->prepare('INSERT INTO table (field, otherField) VALUES(?,?)');
$second = $pdo->prepare('INSERT INTO table (field, otherField) VALUES(?,?)');
$first->execute(array( .. your data (values) .. ));
$second->execute(array( .. your data (values) .. ));
$pdo->commit();
$sql ='START TRANSACTION;
INSERT INTO articles (article_id,article_title, article_text, article_date) VALUES (NULL,?, ?, NOW());
INSERT INTO images (article_id, image_caption) VALUES(LAST_INSERT_ID(),?);
COMMIT;';

Categories