I have some issues with my code. It seems like I'm not able to have multiple prepared statements which seems a little unusual to me.
I would be glad if you can spot an error or help me because I can't figure out the issue.
My error:
Fatal error: Call to a member function bind_param() on boolean in /Applications/XAMPP/xamppfiles/htdocs/platform/creating_user.php on line 37
I am trying to check if the users email already exists in the database and then register the user.
The code works fine when i dont execute the $check.
$check->execute();
I would also like some response on my workflow (the way my code is built up). is it okay?
Thanks!
<?php
$db = new mysqli("localhost","root","","database");
session_start();
if (isset($_POST)){
if(
!empty($_POST["name"])
& !empty($_POST["city"])
& !empty($_POST["zip"])
& !empty($_POST["email"])
& !empty($_POST["tel"])
& !empty($_POST["password"])
) {
$name = encrypt($_POST["name"]);
$city = encrypt($_POST["city"]);
$zip = encrypt($_POST["zip"]);
$email = encrypt($_POST["email"]);
$tel = encrypt($_POST["tel"]);
$password = encrypt($_POST["password"]);
if(!empty($name) && !empty($city) && !empty($zip) && !empty($email) && !empty($tel) && !empty($password)) {
$check = $db->prepare("SELECT email FROM user WHERE email = ?");
$check->bind_param('s', $email);
$check->execute();
if ($check->num_rows == 1) {
header("Location: index.php");
die();
} else {
$insert = $db->prepare("INSERT INTO user (name, city, zip, email, tel, password, created) VALUES (?, ?, ?, ?, ?, ?, NOW())");
$insert->bind_param("ssssss",$name, $city, $zip, $email, $tel, $password);
if ($insert->execute()){
$db->close();
$_SESSION["user"] = $email;
header("Location: created_user");
die();
} else {
header("Location: create-user");
die();
}
}
} else {
header("Location: create-user");
die();
}
} else {
header("Location: create-user");
die();
}
} else {
header("Location: create-user");
die();
}
?>
On php.net I found this
mysqli::prepare() returns a statement object or FALSE if an error
occurred.
So this mean something is wrong with your $db object. This could be:
Wrong password
Wrong username
...
Related
I have table of users which have following columns: user_id,username,first_name,last_name, email,token,password,location, phone.
I have 2 forms on two different pages. 1. registration.php 2. user_info.php.
In registration.php I'm getting user's email, username, and password. In user_info.php I'm getting user's first, lastname, country, phone.
I want to insert both form data in 1 row. so Is there any way?
right now with my code. it inserts info from both forms into database but it's inserting in each form data in 2 different rows.
here is my registration.php
<?php
if (isset($_POST['signup-submit'])) {
$url = "https://www.google.com/recaptcha/api/siteverify";
$data = ['secret' => "[xxxx]", 'response' => $_POST['token'], 'remoteip' => $_SERVER['REMOTE_ADDR']];
$options = array('http' => array('header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data)));
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$res = json_decode($response, true);
if ($res['success'] == true) {
require("dbh.inc.php");
require("functions.php");
$username = escape($_POST['username']);
$email = escape($_POST['email']);
$token = bin2hex(random_bytes(50));
$password = escape($_POST['password']);
$passwordRepeat = escape($_POST['confirm_password']);
if (empty($username) || empty($email) || empty($password) || empty($passwordRepeat)) {
header("Location: ../registration.php?error=emptyfields");
exit();
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) || !preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../registration.php?error=invalidmailuid");
exit();
} elseif (strlen($username) <= '6') {
header("Location: ../registration.php?error=usernamecheck");
exit();
} elseif (strlen($password) <= '8') {
header("Location: ../registration.php?error=passwordcheck");
exit();
} elseif ($password !== $passwordRepeat) {
header("Location: ../registration.php?error=passwordverify");
exit();
} else {
$sql = "SELECT username, email FROM users WHERE username = ? AND email = ?";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../registration.php?error=sqlerror");
exit();
} else {
mysqli_stmt_bind_param($stmt, "ss", $username, $email);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../registration.php?error=usermailtaken");
exit();
} else {
$sql = "INSERT INTO users(username, email, password, token, joined) VALUES(?, ?, ?, ?, now())";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../registration.php?error=sqlerror2");
exit();
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "ssss", $username, $email, $hashed_password, $token);
mysqli_stmt_execute($stmt);
header("Location: ../user_info.php");
exit();
}
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($connection);
} else {
header("Location: ../registration.php?error=captcha");
exit();
}
} else {
header("Location: ../registration.php?error=emptyfields");
exit();
}
here is my user_info.php
<?php
if (isset($_POST['profile-submit'])) {
require("dbh.inc.php");
require("functions.php");
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$location = $_POST['location'];
$phone = $_POST['phone_number'];
if (empty($first_name) || empty($last_name) || empty($location) || empty($phone)) {
header("Location: ../user_info.php?error=emptyfields");
exit();
} else {
$sql = "INSERT INTO users(first_name, last_name, location, phone) VALUES(?, ?, ?, ?)";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../user_info.php?error=sqlerror");
exit();
} else {
mysqli_stmt_bind_param($stmt, "sssi", $first_name, $last_name, $location, $phone);
mysqli_stmt_execute($stmt);
header("Location: ../index.php?signup=success");
exit();
}
}
mysqli_stmt_close($stmt);
mysqli_close($connection);
} else {
header("Location: ../user_info.php?error");
exit();
}
You need to use an UPDATE instead of an INSERT on user_info.php
INSERT adds new rows. https://dev.mysql.com/doc/refman/8.0/en/insert.html
INSERT inserts new rows into an existing table.
UPDATE modifies data in a row. https://dev.mysql.com/doc/refman/8.0/en/update.html
UPDATE is a DML statement that modifies rows in a table.
When you do an UPDATE you need to add a WHERE clause to update only the row you want. You usually do this with the primary key which I assume in this case is user_id.
You can use mysqli_insert_id($connection) to get the last id inserted after your INSERT query runs. I suggest then storing that in a $_SESSION variable and then accessing that on user_info.php rather than passing is via POST or GET. That way, another user can't just type in an ID in the GET or POST request and update another user's info. Here is some code to guide you.
registration.php
//start the session
session_start();
...
...
} else {
mysqli_stmt_bind_param($stmt, "sssi", $first_name, $last_name, $location, $phone);
mysqli_stmt_execute($stmt);
$_SESSION['user_id'] = mysqli_insert_id($connection);
header("Location: ../index.php?signup=success");
exit();
}
}
....
....
user_info.php
....
....
if (empty($first_name) || empty($last_name) || empty($location) || empty($phone) || !isset($_SESSION['user_id')) {
header("Location: ../user_info.php?error=emptyfields");
exit();
} else {
$sql = "UPDATE users SET first_name = ?, last_name = ?, location = ?, phone =? WHERE user_id = ?";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../user_info.php?error=sqlerror");
exit();
} else {
mysqli_stmt_bind_param($stmt, "sssi", $first_name, $last_name, $location, $phone, $_SESSION['user_id']);
mysqli_stmt_execute($stmt);
header("Location: ../index.php?signup=success");
exit();
}
....
....
in registration.php you need to get the last inserted Id before going to user_info.php
mysqli_stmt_bind_param($stmt, "ssss", $username, $email, $hashed_password, $token);
mysqli_stmt_execute($stmt);
//get last inserted id
$last_id = mysqli_insert_id($connection);
header("Location: ../user_info.php?id='.$last_id.'");
exit();
in user_info.php use update in your query with where id = $_GET['id']
if (isset($_POST['profile-submit'])) {
require("dbh.inc.php");
require("functions.php");
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$location = $_POST['location'];
$phone = $_POST['phone_number'];
if (empty($first_name) || empty($last_name) || empty($location) || empty($phone)) {
header("Location: ../user_info.php?error=emptyfields");
exit();
} else {
$sql = "UPDATE users SET first_name = ?, last_name = ?, location = ?, phone =? WHERE id = ?";
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../user_info.php?error=sqlerror");
exit();
} else {
mysqli_stmt_bind_param($stmt, "sssii", $first_name, $last_name, $location, $phone, $_GET['id']);
mysqli_stmt_execute($stmt);
header("Location: ../index.php?signup=success");
exit();
}
}
mysqli_stmt_close($stmt);
mysqli_close($connection);
}else {
header("Location: ../user_info.php?error");
exit();}
Registering members and allowing them to login (updating tables etc) all worked fine up until I made this change recently. Which essentially said, if this person logs in check if they are member or admin and show them a different page depending on what they are). I manually went into the table and set existing users as a 'member' apart from 1 person who was 'admin'. Now when I try to sign a user up it doesn't insert into the tblUsers anymore.
The change I made is below:
<?php
if ($_SESSION['fldUserLevel'] == 'Member'){
?>
// PAGE DETAILS
<?php
}
?>
^^^ This would show top half of page and then for admin who would see the bottom half of the page:
<?php
if ($_SESSION['fldUserLevel'] == 'Admin'){
?>
// PAGE DETAILS
<?php
}
?>
Since doing this when I sign a user up, the details no longer go into the table, can someone suggest why? Or do I need a script that says all people who sign up, make the UserLevel 'Member'?
Code for signing up:
<?php
if (isset($_POST['signup-submit'])) {
require 'dbh.inc.php';
$username = $_POST['uid'];
$email = $_POST['mail'];
$password = $_POST['pwd'];
$passwordRepeat = $_POST['pwd-repeat'];
// check for any empty inputs.
if (empty($username) || empty($email) || empty($password) || empty($passwordRepeat)) {
header("Location: ../signup.php?error=emptyfields&uid=".$username."&mail=".$email);
exit();
}
// check for an invalid username AND invalid e-mail.
else if (!preg_match("/^[a-zA-Z0-9]*$/", $username) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location: ../signup.php?error=invaliduidmail");
exit();
}
// check for an invalid username. In this case ONLY letters and numbers.
else if (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../signup.php?error=invaliduid&mail=".$email);
exit();
}
// check for an invalid e-mail.
else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location: ../signup.php?error=invalidmail&uid=".$username);
exit();
}
// check if the repeated password is NOT the same.
else if ($password !== $passwordRepeat) {
header("Location: ../signup.php?error=passwordcheck&uid=".$username."&mail=".$email);
exit();
}
else {
// include another error handler here that checks whether or the username is already taken. We HAVE to do this using prepared statements because it is safer!
$sql = "SELECT uidUsers FROM tblUsers WHERE uidUsers=?;";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../signup.php?error=sqlerror");
exit();
}
else {
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCount = mysqli_stmt_num_rows($stmt);
mysqli_stmt_close($stmt);
if ($resultCount > 0) {
header("Location: ../signup.php?error=usertaken&mail=".$email);
exit();
}
else {
$sql = "INSERT INTO tblUsers (uidUsers, emailUsers, pwdUsers) VALUES (?, ?, ?);";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../signup.php?error=sqlerror");
exit();
}
else {
$hashedPwd = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashedPwd);
mysqli_stmt_execute($stmt);
header("Location: ../signup.php?signup=success");
exit();
}
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
else {
header("Location: ../signup.php");
exit();
}
Screenshot of webpage saying successful signup:
Signup Successful Message
Screenshot of table, which shows no entry of Kayz:
Screenshot of phpMyAdmin
Ensure that you have actually set a variable name giving "Member"; or "Admin";, however I would suggest that as Romain.B suggests to read that document on setting default values.
$member = "Member"; or "Admin";
Then your query should be:
$sql = "INSERT INTO tblUsers (uidUsers, emailUsers, pwdUsers, fldUserLevel) VALUES (?, ?, ?, ?);";
Further down you need to include your new variable of $member:
mysqli_stmt_bind_param($stmt, "ssss", $username, $email, $hashedPwd, $member);
im writting a login system, user enter his email and password, script checks if its in database, then checks the password. My Problem, it checks only the first value, the others will be ignored. How do i complete loop through the database and then go to the else part if not successfull?
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start();
$host = htmlspecialchars($_SERVER["HTTP_HOST"]);
$uri = rtrim(dirname(htmlspecialchars($_SERVER["PHP_SELF"])), "/\\");
require_once "db_daten_aktuell.php";
if (isset($_POST['email']) && ($_POST['passwort']))
{
if ($stmt = $mysqli->prepare("SELECT vorname, email, password FROM gast"))
{
$stmt->execute();
$stmt->bind_result($vorname, $email, $password);
while ($stmt->fetch())
{
if ($_POST['email'] == $email)
{
if ($_POST['passwort'] == $password){
$_SESSION["name"] = $vorname;
$_SESSION["login"] = "ok";
$extra = "willkommen.php";
}
}
else
{
$extra = "start.php?f=1";
}
$stmt->close();
}
$mysqli->close();
}
}
header("Location: http://$host$uri/$extra");
?>
Try to change this part
if ($stmt = $mysqli->prepare("SELECT vorname, email, password FROM gast"))
{
$stmt->execute();
to
if ($stmt= $mysqli->prepare("SELECT vorname, email, password FROM gast WHERE email=? AND password=?"));
$stmt->bind_param("ss", $_POST['email'] ,$_POST['passwort']);
$stmt->execute();
This way you can compare email and password first, and do other comparison later depending on the requirements. Please let me know if there is any other issues
<?php
session_start();
//Obtain data from register page
$email = $_POST['email'];
$password = $_POST['password'];
//Check to see user has input
if ($username !='' || $password !='' || $confirmpassword !='' || $email !='') {
if ($password1 == $password2) {
// connect to database
$db = new mysqli('removed', 'removed','removed' ,'removed');
// Check to see if connection was successful
if ($db->connect_errorno) {
die ('Sorry, we are having some issues with our database. We should be back online soon.');
}
// Prepare statement
$query = "INSERT INTO `database`.`users` (
`id` ,
`minecraftusername` ,
`email` ,
`password` ,
`joined` ,
`rank`
)
VALUES (
NULL , ?, ?, ?, NOW( ) , '1'
);";
$stmt=$db->prepare($query);
$stmt->bind_param('sss', $username, $email, $password);
//Execute query
$stmt->execute();
// header("Location: ../default.php");
echo 'You have successfully registered an account!';
} else {
// header("Location: ../default.php");
echo 'Passwords do not match.';
}
} else {
// header("Location: ../default.php");
echo 'Please fill out all the fields';
}
?>
When you try to register, it does echo the registered successfully message, but when I go to phpmyadmin the number of rows hasn't changed.
I am really not sure what errors I have made.
Any help would really be appreciated.
$password = $_POST['password'];
Here you set only $password, but then you expect other variables to exist,
if ($username !='' || $password !='' || $confirmpassword !='' || $email !='') {
if ($password1 == $password2) {
$confirmpassword and $password1 and $password2 are never set. Noted in comments by #RobP and #Ali.
You connect to the database only if $password1 == $password2, and you only die() in that block as well. So you might easily skip that whole block, and not die(), and go on to try to run the INSERT without having connected to the database. Noted in comment from #Erico.
if ($db->connect_errorno) {
It's connect_errno, not "connect_errorno". If that block of code were run, it would generate a notice: PHP Notice: Undefined property: mysqli::$connect_errorno. So this proves that your code to connect to the database was never run.
$stmt=$db->prepare($query);
$stmt->bind_param('sss', $username, $email, $password);
$stmt->execute();
You should always check the return value of prepare() and execute(). They return false if there is any problem with the statement. Like if you had a syntax error, or violated a unique constraint or something. Right now your INSERT might be failing but you'll never know. Also noted in a comment by #sanketh.
Or else you can set mysqli_report(MYSQLI_REPORT_STRICT) to raise exceptions if there's an error. Then you don't need to write code to check the return values, because your script will die if there's any mysqli error. You have to set this report mode before you connect to the database.
Also, you never set a value for $username.
This question already has answers here:
Fatal error: Call to undefined method mysqli_stmt::get_result()
(2 answers)
Closed 9 years ago.
I'm not sure why I keep getting this error but I need some help with it... I'm just trying to check the db to see of the record exists before allowing an insert.
$input_errors = array();
if (!empty($_POST['username'])) {
$user = $_POST['username'];
} else {
$input_errors['username'] = "Must fill out username";
}
$email = filter_input(INPUT_POST, 'usermail', FILTER_VALIDATE_EMAIL);
if (false === $email) {
$input_errors['usermail'] = "Not a valid email address";
}
if(count($input_errors) > 0) {
print_r($input_errors); die();
}
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = ?
OR email = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ss", $user, $email);
$stmt->execute();
$results = $stmt->get_result();
$data = mysqli_fetch_assoc($results);
if ($data['amount'] > 0)
{
print "User already exists";
}
}
else {
$stmt = $mysqli->stmt_init();
if (!$stmt) {
echo "Init failed";
} else {
$cmd = "INSERT INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
if ($stmt->prepare($cmd)) {
$stmt->bind_param('ss', $user, $email );
$stmt->execute();
echo $stmt->affected_rows . " row(s) inserted";
$stmt->close();
} else {
echo "Prepare failed";
}
mysqli_close($mysqli);
}
}
If anyone can lend a helping hand that would be fantastic.
For some reason I just can't stand such long and windy codes.
All you actually need is just
$cmd = "INSERT IGNORE INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
$stmt->prepare($cmd);
$stmt->bind_param('ss', $user, $email);
$stmt->execute();
if (!$stmt->affected_rows)
{
print "User already exists";
}
No need to hassle with extra select query.
No need to hassle with binding results.
No need to hassle with numerous nested if statements (whose logic is flawed and actually spoiled the whole mess).
Make sure your php version is PHP 5.3.0 or higher and you have the mysqlnd driver installed on your server. Otherwise, that function is not available.
Instead, you could use fetch().