Prepared-statement MySQLI: INSERT doesn't work [duplicate] - php

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.
I am a coding beginner and can't solve this error.I tried to create a login/register script but my INSERT statement doesn't work and I can't find the error:/ Sry for my bad english, I am german.
"Fatal error: Call to a member function bind_param() on boolean in"
if (isset($_POST['registrieren']) && $_POST['name'] != "" && $_POST['password'] != "")
{
$url = 'https://www.google.com/recaptcha/api/siteverify';
$privateKey = "???????????????????????????";
$response = file_get_contents($url . "?secret=" . $privateKey . "&response=" . $_POST['g-recaptcha-response'] . "&remoteip=" . $_SERVER['REMOTE_ADDR']);
$data = json_decode($response);
if (isset($data->success) && $data->success == true)
{
$name = $_POST['name'];
$password = $_POST['password'];
$username_exists = $db->prepare("SELECT name from users WHERE name = ? ");
$username_exists->bind_param('s', $name);
$username_exists->execute();
if ($username_exists->num_rows) {
echo "<div class='fehler'>Name bereits vergeben!</div>";
} else {
$verschlüsseln = password_hash($password, PASSWORD_DEFAULT);
$insert = $db->prepare("INSERT INTO users (name, password) VALUES (?, ?)");
$insert->bind_param("ss", $name, $verschlüsseln);
$insert->execute();
$_SESSION['name'] = $name;
$_SESSION['password'] = $password;
header("Location: http://localhost/data/login/me.php");
}
} else {
echo "<div class='fehler'>Captcha-Check failed!</div>";
}
}

The error suggests that the prepare statement has failed but it's not clear which one. The code below is not tested and I wonder whether the accent on the u might have caused issues (?) so I renamed that variable to $hash
<?php
if( !empty( $_POST['registrieren'] ) && !empty( $_POST['name'] ) && !empty( $_POST['password'] ) && !empty( $_POST['g-recaptcha-response'] ) ){
$url = 'https://www.google.com/recaptcha/api/siteverify';
$privateKey = "6LdBNScTAAAAALrn5__S9lfV3EuSFu9Si_gwWeus";
$response = file_get_contents( $url . "?secret=" . $privateKey . "&response=" . $_POST['g-recaptcha-response'] . "&remoteip=" . $_SERVER['REMOTE_ADDR'] );
$data = json_decode( $response );
if( isset( $data->success ) && $data->success == true ) {
$name = $_POST['name'];
$password = $_POST['password'];
$stmt = $db->prepare("SELECT `name` from `users` WHERE `name` = ?;");
if( !$stmt ){
exit('Error preparing sql select statement');
}
$stmt->bind_param( 's', $name );
$stmt->execute();
if ( $stmt->num_rows ) {
echo "<div class='fehler'>Name bereits vergeben!</div>";
} else {
/* release results from previous cmd */
$stmt->free_result();
/* Is it possible that the accent on the 'u' caused problems? */
$hash = password_hash( $password, PASSWORD_DEFAULT );
$stmt = $db->prepare( "INSERT INTO `users` (`name`, `password`) VALUES (?, ?);" );
if( !$stmt ){
exit('Error preparing sql insert statement');
}
$stmt->bind_param( "ss", $name, $hash );
$stmt->execute();
/* again, free the results */
$stmt->free_result();
/* do you really want to store a password in a session variable? */
$_SESSION['name'] = $name;
$_SESSION['password'] = $password;
header("Location: http://localhost/data/login/me.php");
}
} else {
echo "<div class='fehler'>Captcha-Check failed!</div>";
}
}
?>

Related

the username is correct but password is wrong it doesn't redirect

My PHP site is connecting to SQL Server database to then create a session and redirect to the 'dashboard':
If the username and password is wrong it redirects - works good.
If the username exists but the password is wrong, it fails to reload ?
Seems so simple but I'm having trouble, help would be great please.
Also suggestions to make this code better would also be good :)
<?php
session_start();
if ( ! empty( $_POST ) ) {
if ( isset( $_POST['username'] ) && isset( $_POST['password'] ) ) {
$username = $_POST['username'];
$password = $_POST['password'];
$connectionInfo = array( "Database"=>"WebUIUsers", "UID"=>"DBUser", "PWD"=>"Password1234");
$conn = sqlsrv_connect( "sqlserver01", $connectionInfo);
if( $conn ) {
// Connection established
$sql = "SELECT * FROM tbl_webui_users WHERE username='$username'";
$stmt = sqlsrv_query( $conn, $sql );
if(!(sqlsrv_fetch_array( $stmt )) >=1){
header("Location: ./index.php");
}
// if username exists but password is wrong redirect to try again ?
while( $row = sqlsrv_fetch_array( $stmt ) ) {
if( $row[password] === $password ) {
$_SESSION['user_session'] = $username;
header("Location: ./dashboard.php");
sqlsrv_free_stmt( $stmt);
}else{
header("Location: ./index.php");
} //end if( $row[password] == $password )
} //end while( $row = sqlsrv_fetch_array( $stmt ) )
}else{
echo "Connection to database could not be established.";
( print_r( sqlsrv_errors(), true));
} //end if( $conn )
} //end if
} // end if
?>
Тhe actual reason for this unexpected behaviour is that you are calling sqlsrv_fetch_array() twice, so while ($row = sqlsrv_fetch_array($stmt)) { ... } simply doesn't return any rows.
But you need to consider at least the following:
Always use parameters in your statements to prevent possible SQL injection issues. As is mentioned in the documentation ... sqlsrv_query function does both statement preparation and statement execution, and can be used to execute parameterized queries.
Do not store passwords in plaintext in a database.
The following basic example, based on your code, is a possible solution to your problem:
<?php
session_start();
if (!empty($_POST)) {
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$connectionInfo = array("Database"=>"WebUIUsers", "UID"=>"DBUser", "PWD"=>"Password1234");
$conn = sqlsrv_connect("sqlserver01", $connectionInfo);
if ($conn === false) {
//echo "Connection to database could not be established: ".print_r(sqlsrv_errors(), true);
header("Location: ./index.php");
exit;
}
$sql = "SELECT * FROM tbl_webui_users WHERE username = ?";
$prms = array($username);
$stmt = sqlsrv_query($conn, $sql, $prms);
if ($stmt === false) {
//echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
header("Location: ./index.php");
exit;
}
// User doesn't exists
if (!sqlsrv_has_rows($stmt)) {
header("Location: ./index.php");
exit;
}
// User exists, but the password is wrong
$row = sqlsrv_fetch_array($stmt));
if ($row === false) {
header("Location: ./index.php");
exit;
}
if ($row["password"] === $password) {
$_SESSION['user_session'] = $username;
header("Location: ./dashboard.php");
} else {
header("Location: ./index.php");
}
}
}
?>

PHP PDO login code - repeats error, not able to login [ correct username and password is entered]

I am struggling to get the login code to run successfully. It keeps on echoing the "Username or Password incorrect.." section, though the correct username and password in entered. Am I missing something somewhere, please help.
<?php
//Check login details
session_start();
//get user input from the form
if (isset($_POST['Submit'])) {
$username = checkData($_POST['username']);
$password = checkData($_POST['password']);
require ('config.php'); //database connection
global $dbselect;
$qry = 'SELECT username, password
FROM users
WHERE username = :username AND password = :password
LIMIT 1';
$statement = $dbselect->prepare($qry);
$statement->bindValue(':username', $username);
$statement->bindValue(':password', $password);
$statement->execute();
$login = $statement->fetch(PDO::FETCH_ASSOC);
if (count($login) > 0 && password_verify($password, $login['password'])) {
$_SESSION['username'] = $login['username'];
header('location:home.html');
} else {
echo "Username or Password incorrect. Please try again.";
}
$statement->closeCursor();
}
//validate data
function checkData($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
The following worked in test ( up to the password_verify where I used a different test as I have PHP 5.3.2 and hence no password_verify ) ~ hopefully it might prove of benefit.
<?php
session_start();
/* error messages used to display to user */
$ex=array(
0 => 'One or more required POST variables are not set',
1 => 'Both username & password are required',
2 => 'Failed to prepare SQL query',
3 => 'Query failed',
4 => 'No results',
5 => 'Invalid login details'
);
if( $_SERVER['REQUEST_METHOD']=='POST' ){
try{
if( isset( $_POST['Submit'], $_POST['username'], $_POST['password'] ) ) {
$username = !empty( $_POST['username'] ) ? filter_input( INPUT_POST, 'username', FILTER_SANITIZE_STRING ) : false;
$password = !empty( $_POST['password'] ) ? filter_input( INPUT_POST, 'password', FILTER_SANITIZE_STRING ) : false;
if( $username && $password ){
require('config.php');
global $dbselect;/* ??? */
/* use the username in the sql not password & username */
$sql='select `username`, `password`
from `users`
where `username` = :username';
$stmt=$dbselect->prepare( $sql );
/* only proceed if prepared statement succeeded */
if( $stmt ){
$stmt->bindParam( ':username', $username );
$status=$stmt->execute();
if( !$status )throw new Exception('',3);
$rows=$stmt->rowCount();
if( !$rows > 0 )throw new Exception('',4);
$result = $stmt->fetchObject();
$stmt->closeCursor();
/* password_verify is available from PHP 5.5 onwards ~ I have 5.3.2 :( */
if( $result && function_exists('password_verify') && password_verify( $password, $result->password ) ){
/* valid */
$_SESSION['username']=$username;
exit( header('Location: home.html') );
} else {
/* bogus - invalid credentials */
throw new Exception('',5);
}
} else {
/* sql prepared statement failed */
throw new Exception('',2);
}
} else {
/* either username or password was empty */
throw new Exception('',1);
}
} else {
/* one or more POST variables are not set */
throw new Exception('',0);
}
}catch( Exception $e ){
/* set a session variable to ensure error message is displayed only once */
$_SESSION['error']=$ex[ $e->getCode() ];
/* reload the login page with error code */
exit( header( 'Location: ?error=' . $e->getCode() ) );
}
}
?>
<!doctype html>
<html>
<head>
<title>Login</title>
</head>
<body>
<!-- the php/html login page -->
<form method='post'>
<input type='text' name='username' />
<input type='password' name='password' />
<input type='submit' name='Submit' value='Login' />
<?php
if( $_SERVER['REQUEST_METHOD']=='GET' && isset( $_GET['error'], $_SESSION['error'] ) ){
unset( $_SESSION['error'] );
/* display the error message */
echo "<h2 style='color:red'>{$ex[ $_GET['error'] ]}</h2>";
}
?>
</form>
</body>
</html>
/**
* You might need to save a hashed copy of the password at the point of
* user creation, so that you can password_verify the input password against the hashed
* copy returned from the DB.
* something like this :
* $hashed = password_hash($password, PASSWORD_BCRYPT);
* NOTE : I've changed you code to an extent, pls adapt.
*/
//Check login details
session_start();
//get user input from the form
if (isset($_POST['Submit'])) {
$username = checkData($username);
$password = checkData($password);
$dbname = "testo";
$servername = "localhost";
$conn = new PDO("mysql:host=$servername;dbname=$dbname", "root", "");
$parr = array($username,$password);
$qry = 'SELECT username, password, phashed
FROM users
WHERE username = ? AND password = ?
LIMIT 1';
$stmt = $conn->prepare($qry);
$Qres = $stmt->execute($parr);
$login = ($Qres) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : array();
if (count($login) > 0 && password_verify($password, $login[0]['phashed'])) {
$_SESSION['username'] = $login[0]['username'];
header('location:home.html');
} else {
echo "Username or Password incorrect. Please try again.";
}
$conn = null;
}
//validate data
function checkData($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}

Check if email already exist [duplicate]

This question already has answers here:
Check if email already exists in database
(4 answers)
Closed 6 years ago.
How do I check if the email already exist in the database and deny the registration?
MySQL was the one taught to me and I'm currently on a wall using MySQLi.
Here is the code that I'm currently working on using MySQLi:
<?php
$cookie_name = "loggedin";
$servername = "localhost";
$username = "root";
$password = "";
$database = "scholarcaps";
$conn = mysqli_connect($servername, $username, $password, $database);
if (!$conn) {
die("Database connection failed: ".mysqli_connect_error());
}
if (isset($_POST['login']))
{
$user = $_POST['username'];
$pass = $_POST['password'];
$phash = sha1(sha1($pass."salt")."salt");
$sql = "SELECT * FROM users WHERE username='$user' AND password='$phash';";
$result = mysqli_query($conn, $sql);
$count = mysqli_num_rows($result);
if ($count == 1)
{
$cookie_value = $user;
setcookie($cookie_name, $cookie_value, time() + (180), "/");
header("Location: personal.php");
}
else
{
echo "Username or password is incorrect!";
}
}
else if (isset($_POST['register']))
{
$user = $_POST['username'];
$email = $_POST['email'];
$pass = $_POST['password'];
$phash = sha1(sha1($pass."salt")."salt");
$sql = "INSERT INTO users (id, email, username, password) VALUES ('','$email', '$user', '$phash');";
$result = mysqli_query($conn, $sql);
}
?>
Despite using mysqli your code is still vulnerable to sql injection as you directly embed variables in the sql statements - use prepared statements to avoid nasty surprises. The following is not tested but should show how you can use prepared statements. There are better ways of hashing the password - such as password_hash and also password_verify though these are not available in PHP versions prior to 5.5
$response=array();
$cookie_name='loggedin';
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = '';
$dbname = 'scholarcaps';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
if( isset( $_POST['login'] ) ) {
$user = $_POST['username'];
$pass = $_POST['password'];
$phash = sha1( sha1( $pass . "salt" ) . "salt" );
$sql='select `username`, `password` from `users` where `username`=? and `password`=?';
$stmt=$db->prepare( $sql );
if( $stmt ){
$stmt->bind_param( 'ss', $username, $phash );
$result=$stmt->execute();
if( !$result ) $response[]='Query failed';
$stmt->store_result();
$stmt->bind_result( $name, $pwd );
$stmt->fetch();
if( $stmt->num_rows()==0 ) $response[]='No such user';
else {
$stmt->free_result();
$stmt->close();
$db->close();
setcookie( $cookie_name, $user, time() + 180, "/" );
exit( header( "Location: personal.php" ) );
}
$stmt->free_result();
$stmt->close();
$db->close();
/* show errors */
if( !empty( $response ) ){
echo '<ul><li>',implode('</li><li>',$response),'</li></ul>';
}
}
} elseif( $_POST['register'] ){
$user = $_POST['username'];
$email = $_POST['email'];
$pass = $_POST['password'];
$phash = sha1( sha1( $pass . "salt" ) . "salt" );
/* Does the email address already exist? */
$emailfound=false;
$sql='select `email` from `users` where `email`=?';
$stmt=$db->prepare( $sql );
if( $stmt ){
$stmt->bind_param('s',$email);
$result=$stmt->execute();
if( $result ){
$stmt->store_result();
$stmt->bind_result( $emailfound );
$stmt->fetch();
$stmt->free_result();
}
}
if( $emailfound ){
echo 'Sorry, that email address already exists in our database. Please try again with a different address.';
$stmt->close();
$db->close();
} else {
/* the `id` should be automatically generated I assume - hence being omitted here */
$sql='insert into `users` (`email`, `username`, `password`) values (?,?,?);';
$stmt=$db->prepare( $sql );
if( $stmt ){
$stmt->bind_param( 'sss', $email, $username, $phash );
$result=$stmt->execute();
$stmt->free_result();
$stmt->close();
$db->close();
if( $result ) header('Location: login.php');
else{
/* failed to register the user */
}
}
}
}
I solved this problem by setting my email column with unique attribute. After the registration submit you can catch the mysqli_errno(). So you will see if there is a duplicate entry.
You will save a check-query with this solution.
If you don't want to match the email, you just want to make sure an email address exists, you could...
$sql = "SELECT * FROM users WHERE username='$user' AND password='$phash' AND email<>'';";
or, to specify a minimum length...
$sql = "SELECT * FROM users WHERE username='$user' AND password='$phash' AND LEN(email) > 0;";
Use this php function for get record count in db
$count=mysqli_num_rows($result)
after check it more than 0 or not
Try this,
add this code after sha1
$result = mysql_query("select COUNT(id) from users where email='".$email."'");
$count = mysqli_num_rows($result);
if($count > 0){
echo "email exist";
}else
{
$sql = "INSERT INTO users (id, email, username, password) VALUES ('','$email', '$user', '$phash');";
$result = mysqli_query($conn, $sql);
}

prepare statement for insert in php failed in my case

I am using ajax and I can't tell what the error is, but I am certain that the data has been inserted in my database. Here is what I tried:
if(isset($_POST['user_id']) && isset($_POST['content']) && isset($_POST['date']) && isset($_POST['category_id'])){
$content = $_POST['content'];
$date = $_POST['date'];
$user_id = $_POST['user_id'];
$category_id = $_POST['category_id'];
$stmt = $db->prepare("INSERT INTO post_items(`post_id`,`content`,`date`,`user_id`,`category_id`)
VALUES (?,?,?,?)");
$stmt = bind_param('ssii',$content,$date,$user_id,$category_id);
if($stmt->execute()) {
echo mysqli_insert_id($db);
}else{
echo "Something is wrong. Insert failed..";
}
}
My old working version (with the lack of security) is shown below:
if(isset($_POST['user_id']) && isset($_POST['content']) && isset($_POST['date']) && isset($_POST['category_id'])){
$content = $_POST['content'];
$date = $_POST['date'];
$user_id = $_POST['user_id'];
$category_id = $_POST['category_id'];
/* $result = $db->query("INSERT INTO post_items(`content`,`date`,`user_id`,`category_id`)
VALUES (".$content."', '".$date."', '".$user_id."', '".$category_id."')");*/
$stmt = $db->prepare("INSERT INTO post_items(`post_id`,`content`,`date`,`user_id`,`category_id`)
VALUES (?,?,?,?)");
$stmt = bind_param('ssii',$content,$date,$user_id,$category_id);
if($stmt->execute()) {
echo mysqli_insert_id($db);
}else{
echo "Something is wrong. Insert failed..";
}
}
I am not sure what I did wrong here as it is the first time that I have worked with this material.
First of all, you don't bind the same number of parameters as value you assign...
Also, The way you are using bind_param is wrong. It should be
if(isset($_POST['user_id']) && isset($_POST['content']) && isset($_POST['date']) && isset($_POST['category_id'])){
$content = $_POST['content'];
$date = $_POST['date'];
$user_id = $_POST['user_id'];
$category_id = $_POST['category_id'];
$stmt = $db->prepare("INSERT INTO post_items(`content`,`date`,`user_id`,`category_id`)
VALUES (?,?,?,?)");
$stmt->bindParam(1, $content);
...
$stmt->bindParam(4, $category_id);
if($stmt->execute()) {
echo mysqli_insert_id($db);
}else{
echo "Something is wrong. Insert failed..";
}
}
or you could also do the following :
if(isset($_POST['user_id']) && isset($_POST['content']) && isset($_POST['date']) && isset($_POST['category_id'])){
$content = $_POST['content'];
$date = $_POST['date'];
$user_id = $_POST['user_id'];
$category_id = $_POST['category_id'];
$stmt = $db->prepare("INSERT INTO post_items(`content`,`date`,`user_id`,`category_id`)
VALUES (?,?,?,?)");
if($stmt->execute(array($content,$date,$user_id,$category_id))) {
echo mysqli_insert_id($db);
}else{
echo "Something is wrong. Insert failed..";
}
}
also just to let you know, pdo has a method to fetch the last id, so instead of
mysqli_insert_id
you could use
$stmt->lastInsertId()
if(isset($_POST['user_id']) && isset($_POST['content']) && isset($_POST['date']) && isset($_POST['category_id'])){
$content = $_POST['content'];
$date = $_POST['date'];
$user_id = $_POST['user_id'];
$category_id = $_POST['category_id'];
$stmt = $db->prepare("INSERT INTO post_items(`content`,`date`,`user_id`,`category_id`)
VALUES (?,?,?,?)");
$stmt->bindParam(1, $content);
...
$stmt->bindParam(4, $category_id);
if($stmt->execute()) {
echo $stmt->lastInsertId();
}else{
echo "Something is wrong. Insert failed..";
}
}

sql issue with registration form

I have created a registration form ( see code below ). There are two fields for the password, the second serving as a check and upon form submission I check if the input in the fields matches. If they don't a message is successfully sent that the passwords do not match but the new user record is still inserted into the database. How can I prevent record insertion if the password fields do no match?
Here is the code:
<?php
$username = isset( $_POST["username"] ) ? $_POST["username"] : "";
$password = isset( $_POST["password"] ) ? $_POST["password"] : "";
$confirm = isset( $_POST["confirm"] ) ? $_POST["confirm"] : "";
if( !empty( $username ) && !empty( $password ) ) {
if( $password != $confirm )
header( "location:registration.php?msg = Password does not be match." );
$host = "localhost";
$user = "i have put my username here";
$pass = "i have put my pass here";
$link = mysql_connect( $host,$user,$pass ) or die( mysql_error() );
mysql_select_db( "web_db",$link );
$query = "SELECT * FROM users WHERE username = '".mysql_escape_string( $username )."'";
$result = mysql_query( $query );
$count = mysql_num_rows( $result );
if( $count = = 1 ) {
header( "location:registration.php?msg = username already exists" );
} else {
$qry = "INSERT INTO users( username,password )VALUES( '".mysql_escape_string( $username )."', '".mysql_escape_string( $password )."' )";
mysql_query( $qry );
echo "You are successfully registered.";
}
mysql_close( $link );
} else {
header( "location:registration.php?msg = Username or password cannot be blank." );
}
Try this:
if($password != $confirm){
header("location:registration.php?msg=Password does not be match.");
exit;
}
else {
// rest of the code goes here
}
if ($password != $confirm) {
header("location:registration.php?msg=Password does not be match.");
exit();
}
Try using the above code it might help.

Categories