PHP MySQLi prepared statement not inserting data into table - php

I am designing a website with user login and registration with email verification, and when the user registers an account, it will successfully, and correctly, insert the user record into the database in the "users" table.
But when I try to pull the users id that is created when inserted to insert them into a second table for a roster of all members of the site (this is for a gaming clan), it inserts the user id as 0 in the roster table, regardless of what their id is on the "users" table for that user.
heres my code:
if($insert_stmt = $db->prepare("INSERT INTO users (username, password, email, date, actcode) VALUES (?, ?, ?, ?, ?)"))
{
$insert_stmt->bind_param('sssss', $username, $password, $email, $date, $actcode);
$stmt = $db->prepare("SELECT id FROM users WHERE email = ?");
if($stmt)
{
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->fetch();
$stmt->store_result();
$stmt->bind_result($ui);
}
$stmt = $db->prepare("INSERT INTO roster (userid, joindate) VALUES (?, ?)");
if($stmt)
{
$stmt->bind_param('ss', $ui, $date);
$stmt->execute();
}
if(!$insert_stmt->execute()) {
header('Location: error.php?err=Registration failure: INSERT');
}
}
for security reasons I have left certain variables and sections of the code omitted that do not have any bearing on this section causing me a headache.
I can't figure out why it is not inserting the newly creating "id" from "users" for that user account into the "roster" table under the "userid" column.
Also, just to test something, I also went and set a session variable
$_SESSION['uid'] = $ui;
directly after the line
$stmt->store_result($ui);
and echoed it on my index.php file, and it shows the session variable as 0 as well.

You could simply use this function: mysqli::$insert_id instead of writing your second query.
Replace this line:
$stmt = $db->prepare("SELECT id FROM users WHERE email = ?");
With:
$userid = $db->insert_id;
Let me know if this works.

Still wasn't able to get it to work with the the solutions provided, but decided to just merge everything into the users table, which fixed the issue. As far as checking if it is executing, I am putting in some checks to make sure it goes through. Thanks for the help and advise.

Related

Last inserted ID of a table for another table in the same query?

I have a register, were people can register with their username, their email and a password. If this gets successfully transmitted to the database, this data will be inserted into a table called users. Now, I need the last ID from the just registered user for a second table that is called users_tokens, where I obviously want to save a token for every specific user. I've tried to solve this by using $mysql->insert_id; but that returns 0 in the table and I am also curious if this is a safe method since through my websites data gets inserted all the time.
My PHP Script:
$key = getToken(32);
$token = bin2hex(openssl_random_pseudo_bytes(64));
$stmt = $mysql->prepare("INSERT INTO users (name, email, password, verification_key, register_date) VALUES(?,?,?,?,?)");
$stmt->bind_param("sssss", $_POST["name"], $_POST["email"], md5($_POST["password"]), $key, $posted_on);
$lastid = $mysql->insert_id;
$u_token = $mysql->prepare("INSERT INTO users_tokens (uid, token) VALUES(?,?)");
$u_token->bind_param("ss", $lastid, $token);
Any suggestions?
You just need to execute your statement before retrieving insert_id, something like this
$stmt = $mysql->prepare("INSERT INTO users (name, email, password, verification_key, register_date) VALUES(?,?,?,?,?)");
$stmt->bind_param("sssss", $_POST["name"], $_POST["email"], md5($_POST["password"]), $key, $posted_on);
$stmt->execute(); //You should check for correct execution
$lastid = $mysql->insert_id;

conditional insert column values

i am having a problem with inserting records to my tables as i want to insert values into specific columns if only the value is not null, my query goes like this
i have tried:
INSERT INTO users(id,name,phone,address) VALUES($userId,$userName,$userPhone,$userAddress);
but it gives me error if on client side one of the parameters is not sent not all the time the client side send all the parameters (id,name,phone,address) i want to have some kind of condition instead of the handle all combinations to the query to go over this problem
You should be using prepared queries, but your immediate problem is that you aren't quoting anything:
$query = "INSERT INTO users(id,name,phone,address) VALUES('$userId', '$userName', '$userPhone', '$userAddress')";
Now, assuming you're doing this properly using a PDO connection, this is how you should be doing it to protect your database:
$db = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$query = "INSERT INTO users (id, name, phone, address) VALUES (?, ?, ?, ?)";
$stmt = $db->prepare($query);
$result = $stmt->execute(array($userId,$userName,$userPhone,$userAddress));
if ($result) {
//success
} else {
//failure
}
Put ' inside VALUES () like '$userId'.
INSERT INTO users(id,name,phone,address) VALUES('$userId','$userName','$userPhone','$userAddress');
If parameter are not coming, then let it Insert Null in DB Table column. (Allow Null). And, if you don't want to insert NULL in DB Table column, then assign any default value before inserting.

Insert in specific columns with pdo

I have two registration form for users one of them requires more fields to enter data.
My first question is about how to make tables? I think I should make one table because for loging I should connect to one table only
But in this way how should I insert data from the form which has less fields?
I wrote this code:
$id='';
$password = md5($password);
$data = array(':id'=>$id,':password'=>$password,':mobile'=>$mobile, ':email'=>$email);
$stmt = $con->prepare('INSERT INTO users VALUES(:id,:password, :mobile, :email ) ');
$stmt->execute($data);
and it makes an error because there are some other columns in the table like $firstname, $lastname etc. So what should I do?
One way is that I write:
$firstname= '';
$lastname = '';
in this way I insert empty data but is it the correct way?
You should always explicitly name the columns you're working with in all operations, never simply rely on their implicit "order". For INSERT queries, the syntax is:
INSERT INTO users (id, password, mobile, email)
VALUES (:id, :password, :mobile, :email);

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

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