This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
Hey so I've followed a tutorial on how to create a functional registration system with php and all the code seems to work just fine, however the data I input in my registration form doesn't show up in my database even though the script gives me the output that I have successfully registered. Does anyone know a solution to this?
<?php
// Connect to the db
$DATABASE_HOST = 'localhost';
$DATABSE_USER = 'root';
$DATABSE_PASS = '';
$DATABSE_NAME = 'phplogin';
// Try to connect
$con = mysqli_connect($DATABASE_HOST, $DATABSE_USER, $DATABSE_PASS, $DATABSE_NAME);
if(mysqli_connect_errno()) {
//If there is an error stop the script and display the error
exit('Failed to connect to MySQL: '. mysqli_connect_error());
}
//check if the data already exists
if (!isset($_POST['username'], $_POST['password'], $_POST['email'])) {
//Could not get the data that should have been sent
exit('Please register first');
}
//Submitted registration values are not empty
if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['email'])) {
//if empty exit the script
exit('Please complete the register form');
}
//check if the username has been used already
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
//encrypt password
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
//store the results to be able to check the db
if ($stmt->num_rows > 0) {
//username already exists
echo 'Username already used';
} else {
//Insert new account
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {
//hash the password and use password_verify
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['username'], $password, $POST['email']);
$stmt->execute();
echo 'You have succesfully registered, you can now login';
}}
$stmt->close();
} else {
//Something wrong with the sql statement
echo 'Could not prepare Statement!';
}
$con->close();
?>
It is very good practise to add error checking to your code when developing. An easy way to this is to add this at the top of your php page inside php code tags to at least echo errors out on your page -
error_reporting(E_ALL);
ini_set('display_errors', 1);
Your code should look like this, should return a record. If you had error reporting on, it would have told you where the errors are -
// Connect to the db
$DATABASE_HOST = 'localhost';
$DATABSE_USER = 'root';
$DATABSE_PASS = '';
$DATABSE_NAME = 'phplogin';
// Try to connect
$con = mysqli_connect($DATABASE_HOST, $DATABSE_USER, $DATABSE_PASS, $DATABSE_NAME);
if(mysqli_connect_errno()) {
//If there is an error stop the script and display the error
exit('Failed to connect to MySQL: '. mysqli_connect_error());
}
//check if the data already exists
if (!isset($_POST['username']) || !isset(['password']) || !isset($_POST['email'])) {
//Could not get the data that should have been sent
exit('Please register first');
} else {
//check if the username has been used already
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
//encrypt password
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
//username already exists
echo 'Username already used';
} else {
//Insert new account
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {
//hash the password and use password_verify
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['username'], $password, $POST['email']);
$stmt->execute();
echo 'You have succesfully registered, you can now login';
} else {
echo 'Data not inserted...';
}
}
$stmt->close();
}
$con->close();
Related
I'm making a basic registration system with the help of a tutorial; the tutorial doesn't say how to make it so that it verifies if an email the user tried to register with has been taken, but it does so for the username. How do I make it so that it verifies both the username and email are free and not in the database? And yes, I did enter my database details properly, I just removed them for this post.
(By the way, this is a register.php file which the site goes to after entering details and pressing enter in another webpage.)
<?php
$DATABASE_HOST = '';
$DATABASE_USER = '';
$DATABASE_PASS = '';
$DATABASE_NAME = '';
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if (mysqli_connect_errno()) {
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
die ('Email is not valid!');
}
if (preg_match('/[A-Za-z0-9]+/', $_POST['username']) == 0) {
die ('Username is not valid!');
}
if (strlen($_POST['password']) > 20 || strlen($_POST['password']) < 5) {
die ('Password must be between 5 and 20 characters long!');
}
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
echo 'Username exists, please choose another!';
} else {
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['username'], $password, $_POST['email']);
$stmt->execute();
echo 'You have successfully registered, you can now login!';
} else {
echo 'Could not prepare statement!';
}
}
$stmt->close();
} else {
echo 'Could not prepare statement!';
}
$con->close();
?>
Do it the same way you check if the username is already taken. Change your query to select id, password, email from accounts where username = ? or useremail = ?, make sure you add the email in bind_params and if it's already taken, you'll get a row.
Note that you won't be able to tell if the username is taken or if the email is. If you want to be able to tell, you may run two different queries, or compare results as follows.
Just fetch 1 row (limit 1) and if either the username or email address exists, notify the user. The code below should work.
$stmt = $con->prepare('select username, useremail from accounts where username = ? or useremail = ? limit 1');
$stmt->bind_param('ss', $_POST['username'], $_POST['useremail']);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_name, $user_email);
$stmt->fetch();
$stmt->close();
if ($user_name == $_POST['username']) {
// Username is taken
} else if ($user_email == $_POST['useremail']) {
// Email is taken
} else {
// Email and username are both available
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
i have a query using PDO. password match was successful when I enter only strings or number. But when my password contains #& or anything like that it will tell that password is incorrect. Though in my database that was the right password.
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'Data-Six';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data from the login form was submitted, isset() will check if the data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
die ('Please fill both the username and password field!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare('SELECT `used-id`, `username`, `password` FROM `user-list` WHERE `username` = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->bind_param('s', $username);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
}
if ($stmt->num_rows > 0) {
$stmt->bind_result($username, $password, $id);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if ($_POST['password'] === $password) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
?>
The order of variables in bind_result doesn't follow the order of field names in the SQL query.
That said, store_result/bind_result is outdated and inconvenient method which was replaced by get_result that gets you a conventional PHP array.
Here is the code you need:
$sql = 'SELECT `used-id`, `username`, `password` FROM `user-list` WHERE `username` = ?';
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
// if ($_POST['password'] === $password) { come onm you MUST use a hash
if ($user && password_verify($_POST['password'], $user['password']))
{
...
}
as you can see it is much more concise and convenient
I just figured out how to used the PDO statement XD! thanks team. what i did was just rearranged the query to match the Bind-result.
if ($stmt = $con->prepare('SELECT `username`, `password`, `used-id` FROM `user-list` WHERE `username` = ?')) {
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
}
if ($stmt->num_rows > 0) {
$stmt->bind_result($username, $password, $id);
$stmt->fetch();
if ($_POST['password'] === $password) {
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
echo 'Welcome ' . $_SESSION['id'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
This question already has answers here:
Fatal error: Call to a member function close() on a non-object. MySQLi issue
(3 answers)
Closed 4 years ago.
Doing a user creation page for a school project.
The code worked perfectly fine when using localhost, but gave the title’s error upon uploading it to a web host.
The error is on the the “$stmt->close();” which I believe is not being called, but not sure why it works internally on my system.
<?php
/* entering localhost config instead
require_once "config.php";
*/
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_NAME', 'users');
$mysqli = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if($mysqli === false){
die("ERROR: Could not connect. " . $mysqli->connect_error);
}
$username = $password = $confirm_password = "";
$username_err = $password_err = $confirm_password_err = "";
if($_SERVER["REQUEST_METHOD"] == "POST"){
if(empty(trim($_POST["username"]))){
$username_err = "Please enter a username.";
} else{
$sql = "SELECT id FROM users WHERE username = ?";
if($stmt = $mysqli->prepare($sql)){
$stmt->bind_param("s", $param_username);
$param_username = trim($_POST["username"]);
if($stmt->execute()){
$stmt->store_result();
if($stmt->num_rows == 1){
$username_err = "This username is already taken.";
} else{
$username = trim($_POST["username"]);
}
} else{
echo "Something went wrong.";
}
}
$stmt->close();
}
if(empty(trim($_POST["password"]))){
$password_err = "Please enter a password.";
} elseif(strlen(trim($_POST["password"])) < 6){
$password_err = "Password must have atleast 6 characters.";
} else{
$password = trim($_POST["password"]);
}
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Please confirm password.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($password_err) && ($password != $confirm_password)){
$confirm_password_err = "Password did not match.";
}
}
if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){
$sql = "INSERT INTO users (username, password) VALUES (?, ?)";
if($stmt = $mysqli->prepare($sql)){
$stmt->bind_param("ss", $param_username, $param_password);
$param_username = $username;
$param_password = password_hash($password, PASSWORD_DEFAULT);
if($stmt->execute()){
header("location: login.php");
} else{
echo "Something went wrong.";
}
}
$stmt->close();
}
$mysqli->close();
}
?>
Solved
Dumb error
Used
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', 'true');
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
to find that it was simply a character error in the db config file. Sorry to waste your time.
By the way - The passwords are hashed in the database.
You wrote: if($stmt = $mysqli->prepare($sql)){
If the condition does not match $sdmtp will ne null so your $stmt->close(); will fail.
move the line $stmt->close(); into your if execution block.
The other problem you are facing is your confusion about the fact that your code does produce this error on the dev-system (the non-localhost one). This migth be caused by an exception in $mysqli->prepare($sql) on the dev-system.
This question already has answers here:
Fatal error: Call to a member function close() on a non-object. MySQLi issue
(3 answers)
Closed 1 year ago.
This is my code, and i think the issue is with $stmt->close(); as the error says. But i don't know how to fix it. I have searched the other questions but i can't find an answer (at least it's not helping me, the answers are all confusing :) )
Can you guys please help me?
<?php
// Initialize the session
session_start();
// Check if the user is already logged in, if yes then redirect him to
welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: dash.php");
exit;
}
// Include config file
require_once "config.php";
// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["username"]);
}
// Check if password is empty
if(empty(trim($_POST["password"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["password"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM employees WHERE username =
?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $hashed_password);
if($stmt->fetch()){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: dash.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not
valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
$stmt->close();
}
// Close connection
$mysqli->close();
}
?>
This is what i'm getting - img
$stmt->close() needs to be inside if($stmt = $mysqli->prepare($sql)). If that fails, $stmt is set to false so you're trying to call file->close(), which makes no sense. You should also have an else block to display the reason why it failed.
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM employees WHERE username =
?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_username);
// Set parameters
$param_username = $username;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $hashed_password);
if($stmt->fetch()){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: dash.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not
valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
// Close statement
$stmt->close();
} else {
die($mysqli->error);
}
}
Assuming the brackets are aligned...
If it's that line, $stmt = $mysqli->prepare($sql) resulted in $stmt being false. The close method doesn't exist for a boolean. Your code expected a statement object.
So preparing the statement went wrong.
Check the statement for syntax errors or invalid column and table names, etc.
The following lines should be switched together also:
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s" $param_username); // Set parameters
$param_username = $username;
I'm trying to create a "registration" form using php and mysql. The registration form asks for username and password. If any field is empty, it will let the user know which one. If the username is in use, it will also let the user know.
I know the connection to the database is ok, because I created a user that was I manually added into the database.
The strange thing is that my code is working in Cloud9. But, it wont work on a VM instance installed on google cloud.
In cloud9, it adds the user into the DB. In the google instance, it wont.
Can anyone check this and tell me what I;m doing wrong?
Thanks.
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$display = $_POST['display'];
$dbh = new PDO("mysql:host=localhost;dbname=mydb","root",NULL);
$stmt = $dbh->prepare("SELECT username FROM users WHERE username = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
if($stmt->rowCount() == 0 and $username != null and $password != null){
$insert = $dbh->prepare("INSERT INTO users(username,password) VALUES(:username, :password)");
$insert->bindParam(':username', $username);
$insert->bindParam(':password', $password);
$insert->execute();
echo ("The user ".$username. " has been created.");
Try this, before all u need to check
if username and password is not empty because if username is empty i
cant make query valid to select username
check if username is in use
if username not in use, insert data into database
script
<?php
// error_reporting on
error_reporting(1);
ini_set('error_reporting', E_ALL);
$username = $_POST['username'];
$password = $_POST['password'];
// i commented $display variable because i don't see that u using it anywhere
//$display = $_POST['display'];
// database connection
$dbh = new PDO("mysql:host=localhost;dbname=mydb","root","");
// query
$stmt = $dbh->prepare("SELECT username FROM users WHERE username = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
// check if username and password is not empty
if ($username != '' && $password != '')
{
// check if username is in use
if($stmt->rowCount() > 1)
{
echo "Username in use, please choose another one.";
}
else
{
$insert = $dbh->prepare("INSERT INTO users(username,password) VALUES(:username, :password)");
$insert->bindParam(':username', $username);
$insert->bindParam(':password', $password);
$insert->execute();
// if last inserted id is true
if ($dbh->lastInsertId())
{
echo "The user ".$username. " has been created.";
}
else
{
echo "User not registered, please try again.";
}
}
}
else
{
echo "Please enter username and password.";
}
?>