PHP - MySQLi Prepared Statements - php

$name = $_GET['user'];
if(isset($_GET['user']) && strlen($_GET['user'])>0) {
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $db);
$stmt = $mysqli->prepare("SELECT username FROM users WHERE username=?");
$stmt->bind_param('s', $name);
$stmt->execute();
while($stmt->fetch()) {
if($stmt->num_rows == 0) {
header("Location: home?errormsg=notfound");
exit();
}
}
$stmt->store_result();
$stmt->close();
}
$mysqli->close();
So, the above code checks if $_GET['name'] exists in the database, and if it doesn't, to redirect to home?errormsg=notfound but it redirects the usernames which exists in the database to the link 'home?errormsg=notfound' as well. Can you suggest a way to solve this problem?

You have to call $stmt->store_result() before $stmt->num_rows.
And your $stmt->fetch() is not necessary, because you don't use the selected data.
If you call store_result() after num_rows it won't work.
Part of comment from manual page:
If you do not use mysqli_stmt_store_result( ), and immediatley call
this function after executing a prepared statement, this function will
usually return 0 as it has no way to know how many rows are in the
result set as the result set is not saved in memory yet.
So your code should look like this:
$name = $_GET['user'];
if(isset($_GET['user']) && strlen($_GET['user'])>0) {
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $db);
$stmt = $mysqli->prepare("SELECT username FROM users WHERE username=?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 0) {
header("Location: home?errormsg=notfound");
exit();
}
$stmt->close();
}
$mysqli->close();

I have not tried this but maybe it helps.
You are calling $stmt->store_result(); after $stmt->num_rows
Please try moving $stmt->store_result(); before $stmt->num_rows
Example. you can see here

Related

PHP/MySQL: Check if username exists

I'm a beginner in php and I want to check if the username entered already exists.
Here is my code.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
include "connect.php";
ValidateUser();
}
function ValidateUser()
{
if (!empty($_POST['username']) AND !empty($_POST['password'])) {
$queryrow=mysqli_query("SELECT * FROM websiteusers WHERE username = '$_POST['username']'");
if ($rows=mysqli_num_rows($queryrow)=0) {
RegisterUser();
}
}
function RegisterUser() {
echo "works up to here";
}
?>
It doesn't even give me an error despite turning error reporting on.
Have you even initialized a mysqli_connect?
$Connection = mysqli_connect("host","user","pass","database");
Then pass it to a function which uses mysqli_query() by:
function foo ($DB){
mysqli_query($DB,"QUERY HERE");
// Do other stuff
return /* Whatever you wish to return here*/
}
foo($Connection);
What you are trying to achieve can be done very easily with the following code. A bigger concern is security. It is good practice to both sanitize your input every time the user has a chance to input text.
Also, using prepared query's will put yet another layer of security.
Although this isn't using your provided code directly, I believe it is good to teach good habits.
If you have any questions feel free to ask.
$username = $_POST['username']; <-- sanitize this
$message = null;
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
if ($stmt->num_rows() > 0) {
RegisterUser();
} else {
$message .= 'username already exists';
}
Later on when you require more items to be queried, or more results to be bound:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username); <-- the "s" means the argument is a strings, if a argument is stored as an int use "i", but one character for each argument is required.
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
Multiple Arguments:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=? AND authenticated=?");
$stmt->bind_param('si', $username,$isauthenticated); <-- second argument is a INT or BOOL
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql,$passwordsql,$other1sql,$other2sql);
$stmt->fetch();
When your expecting multiple results, and lets say you want to dump them into arrays:
$userarray = array();
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
while($stmt->fetch()){
array_push($userarray, $usernamesql);
}
$userarray is now an array of all the results fetched from the database.
Here is the right way to do this:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if(check_user($mysqli, $_POST['username']){
registerUser();
}else{
echo 'user exist, cannot register';
}
}
function check_user($conn, $username){
$query = "SELECT * FROM websiteusers WHERE username = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->close();
}
return $stmt->num_rows === 0;
}
function registerUser() {
echo "registering user ...";
}
Read up on prepared statement

mysqli php sql statement does not execute

I have the strangest problem and I can figure out what is happening. There are no error being displayed and I've var_dumped $stmt and for will just not return anything.
The test data that i am trying to retrieve is correct and when i try the statement manually through phpmyadmin it would perfectly so I'm stumped any ideas?
$sql = "SELECT UserID,Password FROM Account WHERE ProfileName = ? OR Email = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$username = strtolower($username);
$stmt->bind_param('ss', $username, $username);
$stmt->bind_result($userID, $dbPassword);
$stmt->execute();
$stmt->fetch();
The bind_result() call must be done after execute() not before.
Change to:
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
$stmt->fetch();
From the Manual:
Note that all columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
Also, you can narrow down the problem by checking if prepare() succeeded and then subsequently if there are any rows:
if($stmt = $conn->prepare($sql))
{
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
if($stmt->num_rows > 0)
{
$stmt->fetch();
}
else
{
echo 'Query succeeded, but no rows found!';
}
}
else
{
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
// use trigger_error() not echo in production, after development
}
If prepare() fails, it means there is a either a connection error, syntax error or missing table/field name in the query.

PHP Prepared Statement/Bind Param Code Crashing

Can someone explain why this gives me a 500 internal server error? I tried adding some sql injection protection and I'm not sure what I'm doing wrong. Should I be doing this in an object oriented style instead of procedural?
<?php
$conn = mysqli_connect($host, $user, $pwd)or die("Error connecting to database.");
mysqli_select_db($conn, $db) or die("Couldn't select the database.");
$username = $_POST['username'];
$password = $_POST['password'];
$stmt = mysqli_stmt_init($conn);
$query = "SELECT * FROM Users WHERE email=? AND password=?";
mysqli_stmt_prepare($stmt, $query) or die("Failed to prepare statement.");
mysqli_stmt_bind_param($stmt, "ss", $username, $password);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$count = mysqli_num_rows($result);
if($count == 1){
//Log in successful
}
else {
//Wrong Username or Password
}
mysqli_close($conn);
?>
mysqli_stmt_get_result is available in PHP 5.3, but I am running 5.1. Also, the mysqlnd driver must be installed for this call to work.
For more information, see Call to undefined method mysqli_stmt::get_result

Catchable fatal error: Object of class PDOStatement could not be converted to string

I am getting the following error when attempting to match values on database with those passed in a form to check if a user exists.
Catchable fatal error: Object of class PDOStatement could not be
converted to string
This is the code I'm using:
//Check users login details
function match_login($username, $password){
//If the button has been clicked get the variables
try{
$dbh = new PDO("mysql:host=localhost;dbname=mjbox","root", "usbw");
} catch( PDOException $e ) {
echo $e->getMessage();
}
$stmt = $dbh->prepare("SELECT * FROM mjbox WHERE username=? AND password=?");
$stmt->bindParam(1, $username);
$stmt->bindParam(2, $password);
$stmt->execute();
$result = mysql_query($stmt);
if( mysql_num_rows($result) > 0 ){
echo 'There is a match!';
}else{
echo 'nooooo';
}
}
mysql_query() and PDO are not compatible and cannot be used together. You're attempting to pass the PDO statement object to mysql_query() which expects a string. Instead, you want to fetch rows from $stmt via one of PDO's fetching methods, or check the number of rows returned with rowCount():
$stmt = $dbh->prepare("SELECT * FROM mjbox WHERE username=? AND password=?");
$stmt->bindParam(1, $username);
$stmt->bindParam(2, $password);
if ($stmt->execute()) {
// get the rowcount
$numrows = $stmt->rowCount();
if ($numrows > 0) {
// match
// Fetch rows
$rowset = $stmt->fetchAll();
}
else {
// no rows
}
}
MySQL and PHP5/PDO don't work well with returning the number of rows. After your new PDO(), issue:
$dbh->setAttribute(PDO::MYSQL_ATTR_FOUND_ROWS, true);
Then issues your query...
$stmt = $dbh->prepare("SELECT * FROM mjbox WHERE username=? AND password=?");
$stmt->bindParam(1, $username);
$stmt->bindParam(2, $password);
$stmt->execute();
// number of rows returned
if($stmt->rowCount()){
// ... matches
}else{
// .. no match
}
Otherwise your rowCount would be either bool 0, or null/throw error.

MySQLi Prepared Statement Query Issue

I'm relatively new to MySQLi prepared statements, and running into an error. Take this code:
$user = 'admin';
$pass = 'admin';
if ($stmt = $mysqli->query("SELECT * FROM members WHERE username='$user' AND password='$pass'"))
{
echo $stmt->num_rows;
}
This will display "1", as it should.
This next piece of code though, returns "0":
$user = 'admin';
$pass = 'admin';
if ($stmt = $mysqli->prepare("SELECT * FROM members WHERE username=? AND password=?"))
{
$stmt->bind_param("ss", $user, $pass);
$stmt->execute();
echo $stmt->num_rows;
}
Any ideas why?
you need to call store_result() before you get the number of rows
$user = 'admin';
$pass = 'admin';
if ($stmt = $mysqli->prepare("SELECT * FROM members WHERE username=? AND password=?"))
{
$stmt->bind_param("ss", $user, $pass);
$stmt->execute();
$stmt->store_result(); // add this line
echo $stmt->num_rows;
}

Categories