Insert not working, but select finds the data on same page - php

I'm inserting a simple entry into a database-table using PDO (php/mysql). The connection is set up correctly and it seems that the data is inserted. Later on the same page (after the insertion) I call a select statement to get all data from that table. It returns everything, including the newly inserted column (and it's incremented id).
But when I refresh the site - or just have a look at the table in phpmyadmin - the new entry is gone... And there is no delete code yet.
Here is the code for insertion
// prep statement
$stmt = $pdo->prepare("INSERT INTO garage (created_at, created_by, modified_at, modified_by, caption, description, picture) VALUES (:created_at, :created_by, :modified_at, :modified_by, :caption, :description, :picture);");
// binding params, all rows return true
$stmt->bindParam(":created_at", $ts, PDO::PARAM_STR);
$stmt->bindParam(":created_by", $user_id, PDO::PARAM_INT);
$stmt->bindParam(":modified_at", $ts, PDO::PARAM_STR);
$stmt->bindParam(":modified_by", $user_id, PDO::PARAM_INT);
$stmt->bindParam(":caption", $caption, PDO::PARAM_STR);
$stmt->bindParam(":description", $description, PDO::PARAM_STR);
$stmt->bindParam(":picture", $filename, PDO::PARAM_STR);
$stmt->execute(); // returns true
A few lines of code later:
$selStmt = $pdo->prepare("SELECT id, caption, description, picture FROM garage;");
$selStmt->execute();
while ($row = $selStmt->fetchObject()) {
echo $row->id; // output is working, id is next increment
}
Any suggestions? Thanks in advance!

Related

PHP - using a variable as part of a column name in an INSERT INTO MySQL statement

I have a database set up and there are 2 different columns and I want to insert values into one of those two columns dynamically based on an ID that is passed in from $_GET. I have the bindParam variable part working, but I'm not sure how to use a variable in the INSERT INTO portion of the statement.
One column is called product1_vote and the other is product2_vote. I am getting the 1 or 2 from $_GET and I want to pass that into the prepare call to determine which column to update.
$productID = $_GET['id'];
$stmt = $pdo->prepare('INSERT INTO products (id, title, product1_vote)
VALUES(:id, :title, :product1_vote);
$id = $pdo->lastInsertId();
$title = 'Test';
$date = date('m/d/Y h:i:s', time());
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':title', $title, PDO::PARAM_STR);
$stmt->bindParam(':product1_vote', $date, PDO::PARAM_STR);
How would I go about changing the INSERT INTO part to work dynamically instead of the current hardcoded product1_vote.
Something like this to give you an idea of what I'm after:
$stmt = $pdo->prepare('INSERT INTO products (id, title, product.$productID._vote)
VALUES(:id, :title, :product.$productID._vote);
$id = $pdo->lastInsertId();
$title = 'Test';
$date = date('m/d/Y h:i:s', time());
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':title', $title, PDO::PARAM_STR);
$stmt->bindParam(':product.$productID._vote', $date, PDO::PARAM_STR);
You can't parameterise a column name, but also, to guard against SQL injection you don't want to allow direct user input into the query without validation.
A common solution to this is to make a "whitelist" of allowed values and ensure that the user-provided value matches one of them before including it in the query.
For example:
$productID = $_GET['id'];
$voteIDs = ["1", "2"];
if (!in_array($productID, $voteIDs)) {
echo "invalid input value";
die();
};
$stmt = $pdo->prepare('INSERT INTO products (id, title, product'.$productID.'_vote)
VALUES(:id, :title, :product1_vote);
P.S. It's possible this has arisen because your database could be better normalised. If you have multiple votes per product, consider storing them in a separate "productVotes" table with a foreign key back to the products table. Then you wouldn't need to vary the column names in your query.

Why can I only insert a value once for each columnID

I am inserting data to my db using this:
$insertPlayerFix = "INSERT INTO playerfixtures (fixture_id, player_id, goals_scored) VALUE (?,?,?)";
$stmt = $conn->prepare($insertPlayerFix);
$stmt->bind_param('sss', $fixtureFix_ID,$playerFix_ID,$goalsScored);
$stmt->execute();
$stmt->store_result();
This works fine until I have data for each of the fixtureID's. It then seemingly inserts data and gives me the success message but nothing new is stored.
It is like I am telling it to check for fixtureID and if > 0 to not do anything(which I am not, obviously).
could be you have an autoincrement column for fixture_id
in this case you should not use this column in you insert clause
eg:
$insertPlayerFix = "INSERT INTO playerfixtures ( player_id, goals_scored) VALUE (?,?)";
$insertPlayerFix = "INSERT INTO playerfixtures ( player_id, goals_scored) VALUE (?,?)";
$stmt = $conn->prepare($insertPlayerFix);
$stmt->bind_param('ss', $fixtureFix_ID,$playerFix_ID,$goalsScored);
$stmt->execute();
$stmt->store_result();
and id normally are integer so check for the correct data type and eventually modify you binding

Searching a file and storing it in a variable php

I have a text file that goes like this
1 wordsgohere
2 morewordsgohere
3 yougetthepoint
I want to assign one of the strings above to the user_id of that person. So say you are the third person to register, your user_id is 3 and your deposit_id would be 'yougetthepoint'. However when I echo user_id it's always 0 even though there are 2 or three users in the database and when looking at the database the id number increases. It won't put the user in the data base either. If I replace deposit_id with something else it will put the user in the data base. I think it's because new_str never gets defined.
// id of new user
$user_id = $this->db_connection->lastInsertId();
echo $user_id;
// searches text file for address
$lines_array = file("test.txt");
foreach($lines_array as $line) {
echo $line;
if(strpos($line, $user_id) != false) {
list(, $new_str) = explode($user_id, $line);
}
}
// write new users data into database
$query_new_user_insert = $this->db_connection->prepare('INSERT INTO users (deposit_id, user_name, user_password_hash, user_email, user_activation_hash, user_registration_ip, user_registration_datetime) VALUES(:deposit_id, :user_name, :user_password_hash, :user_email, :user_activation_hash, :user_registration_ip, now())');
$query_new_user_insert->bindValue(':deposit_id', $new_str, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_password_hash', $user_password_hash, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_activation_hash', $user_activation_hash, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_registration_ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR);
$query_new_user_insert->execute();
Any help would be great, thanks.
As some people mention in your comments you should check the order of the statements.
First you insert the row into your database. On execute the Database will generate the ID which u can retrieve afterwards.
Now you want to add the Deposit_id to the generated entry. Just Update the Entry (UPDATE users SET deposit_id=:deposit_id WHERE user_id=:user_id;).
But I think you will get a result, which you don't want.
Is the number in the textfile really the user_id? or just an enumeration? you could just parse it and create an array containing the deposit_ids in the order of the file. Now your can Insert all rows by running one insert per array-entry

MySQL row inserted but not saved?

I am inserting a row into a MySQL table from PHP and running a query right after the insert to get the key value of the row that was just inserted like so:
$stmt = $this->db->prepare("INSERT INTO user(vFirstName, vLastName, vEmail, vPassword, iSkilllevelid, vTournaments, vDays, dAddedDate, eStatus) VALUES (?,?,?,?,4,'Pick-Up','Saturday',NOW(),'Active')");
$stmt->bind_param("ssss", $firstName, $lastName, $email, $pwd);
$stmt->execute();
$stmt->close();
$stmt = $this->db->prepare('SELECT iUserId FROM user WHERE vEmail=?');
$stmt->bind_param("s", $email);
$stmt->execute();
$stmt->bind_result($iUserId);
while ($stmt->fetch()) {
break;
}
After this code executes, $iUserId has the correct auto incremented key value (1143 for instance), but when I actually look at the database table, the row with that key (1143) does not exist. How is that possible??
Instead of selecting from the table after insertion, you should use mysqli::$insert_id:
$stmt = $this->db->prepare('
INSERT INTO user
(vFirstName, vLastName, vEmail, vPassword, iSkilllevelid,
vTournaments, vDays, dAddedDate, eStatus)
VALUES
(?,?,?,?,4,"Pick-Up","Saturday",NOW(),"Active")
');
$stmt->bind_param('ssss', $firstName, $lastName, $email, $pwd);
$stmt->execute();
$iUserId = $this->db->insert_id;
$stmt->close();
As to why the inserted data is not appearing from other connections, it seems likely that your transaction has not been committed:
$this->db->commit();

PHP PDO Transactions?

I have a signup page and basically I need data inserted into 4 tables. I'm new to PDO and am confused over something.
Basically if any of the inserts fail I don't want anything added to the database, that seems simple enough.
My confusion is, I need to first insert the users username, email, password etc in my users table so I can get (not sure how) using PDO the uid MySQL has given my user (auto incremented by mysql). I need the user uid MySQL gave my user for the other tables as the other tables needs the uid so everything is linked properly together. My tables are InnoDB and I have foreign keys going from users_profiles(user_uid), users_status(user_uid), users_roles(user_uid) to the users.user_uid so they are all linked together.
But at the same time I want to ensure that if for example after data is inserted in the users table (so I can get the uid MySQL gave user) that if any of the other inserts fail that it removes the data that was inserted into the users table.
I thinks it's best I show my code; I have commented out the code and have explained in the code which may make it easier to understand.
// Begin our transaction, we need to insert data into 4 tables:
// users, users_status, users_roles, users_profiles
// connect to database
$dbh = sql_con();
// begin transaction
$dbh->beginTransaction();
try {
// this query inserts data into the `users` table
$stmt = $dbh->prepare('
INSERT INTO `users`
(users_status, user_login, user_pass, user_email, user_registered)
VALUES
(?, ?, ?, ?, NOW())');
$stmt->bindParam(1, $userstatus, PDO::PARAM_STR);
$stmt->bindParam(2, $username, PDO::PARAM_STR);
$stmt->bindParam(3, $HashedPassword, PDO::PARAM_STR);
$stmt->bindParam(4, $email, PDO::PARAM_STR);
$stmt->execute();
// get user_uid from insert for use in other tables below
$lastInsertID = $dbh->lastInsertId();
// this query inserts data into the `users_status` table
$stmt = $dbh->prepare('
INSERT INTO `users_status`
(user_uid, user_activation_key)
VALUES
(?, ?)');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->bindParam(2, $activationkey, PDO::PARAM_STR);
$stmt->execute();
// this query inserts data into the `users_roles` table
$stmt = $dbh->prepare('
INSERT INTO `users_roles`
(user_uid, user_role)
VALUES
(?, ?)');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->bindParam(2, SUBSCRIBER_ROLE, PDO::PARAM_STR);
$stmt->execute();
// this query inserts data into the `users_profiles` table
$stmt = $dbh->prepare('
INSERT INTO `users_profiles`
(user_uid)
VALUES
(?)');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->execute();
// commit transaction
$dbh->commit();
} // any errors from the above database queries will be catched
catch (PDOException $e) {
// roll back transaction
$dbh->rollback();
// log any errors to file
ExceptionErrorHandler($e);
require_once($footer_inc);
exit;
}
I'm new to PDO and there maybe errors or problems above I have yet to notice because I can't test yet until I figure out my problem.
I need to know how I can insert the users data in the users table first so i can get the uid MySQL gave my user
Then get the uid as I need it for the other tables
But at the same time if a query fails for whatever reason after inserting into users table that the data is also deleted from the users table aswell.
This function returns primary key of just inserted record: PDO::lastInsertId
You will need it for NEED_USERS_UID_FOR_HERE parameter. Use it just after INSERT statement.
Since you started a transaction, data will not be inserted into any table if any error occures provided you use InnoDB engine for your MySQL tables (MyISAM doesn't support transactions).

Categories