PHP MySQLi prepared statement for SELECT (avoid SQL Injection) - php

is this the correct way to avoid SQL Injection in this SELECT?
// --[ Method ]---------------------------------------------------------------
//
// - Purpose : Check if provided $email (taken from user input) exists in the DB
//
// -----------------------------------------------------------------------------
function DB_EmailExists($email)
{
//
if(DB_Connect() == false)
{
echo mysqli_error();
return false;
}
//
$stmt = $GLOBALS['global_db_link']->prepare("SELECT * FROM ".$GLOBALS['global_db_table_users']." WHERE Email=?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
$stmt->close();
//
if ($numrows==0)
{
DB_Disconnect();
return false;
}
//
DB_Disconnect();
return true;
}

Yes, that works. But no need to SELECT *, just use SELECT email

Related

Converting a normal OOP SQLi statement to a Prepared Statement

I have the following normal User class statement that I'm trying to convert to a prepared statement.
public function didReceiveRequest($user_from) {
$user_to = $this->user['username'];
$check_request_query = mysqli_query($this->con, "SELECT * FROM friend_requests WHERE user_to='$user_to' AND user_from='$user_from'");
if (mysqli_num_rows($check_request_query) > 0) {
return true;
}
else {
return false;
}
}
I'm new to prepared statements and have been doing pretty well throughout the User class, but am still having trouble with a few. Being new, I don't follow the logic as well, so please go easy. Here is what I have so far:
public function didReceiveRequest($user_from){
$user_to = $this->user['username'];
$check_request = $this->con->stmt_init();
$check_request->prepare('SELECT * FROM friend_requests WHERE user_to=? AND user_from=?');
$check_request->bind_param('ss', $user_to, $user_from);
$check_request->execute();
$result = check_request->get_result();
$data = $result->fetch_assoc();
$check_request->free_result();
$check_request->close();
if($data > 0){
return true;
}else{
return false;}
}
So a couple things abt this: 1)I know there is probably a better and more efficient way to do this. And 2) Will what I have return the same result as what was there (with normal statement) previously. I don't want to mix up calls from my dependent pages.
Here is how you would use MySqli prepared statements for your case example.
public function didReceiveRequest($user_from) {
$query = "SELECT *
FROM friend_requests
WHERE user_to = ? AND user_from = ?";
$user_to = $this->user['username'];
$stmt = $this->con->prepare($query);
$stmt->bind_param(ss, $user_to, $user_from); //set your bindings
$stmt->execute();
//$results = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);//Use if you want to see results.
if($stmt->num_rows !== 0) {
return TRUE;
}else{
return FALSE;
}
}
Here is a really good link to read that teaches you how to use prepared statements with MySqli. I would bookmark this link and refer to it often. MySqli prepared statements
Using prepared statements does not affect how you receive the results from you query.
The difference I see in what was provided as an answer is $result = $stmt->get_result(); Again being new to prepared statements I'm not 100% that this is the reason above code throws an error, but this code works.
public function didReceiveRequest($user_from) {
$user_to = $this->user['username'];
$stmt = $this->con->stmt_init();
$stmt->prepare('SELECT * FROM friend_requests WHERE user_to=? AND user_from=?');
$stmt->bind_param('ss', $user_to, $user_from);
$stmt->execute();
$result = $stmt->get_result();
$qty = $result->num_rows;
$stmt->free_result();
$stmt->close();
if($qty > 0) {
return true;
}else{
return false;
}
}

Retrieving data from database using prepared statement

I'm having problem retrieving my data from my database. Here's my code:
function login($email, $password) {
$stmt = $this->conn->prepare("SELECT id FROM lms_admin_users WHERE email=?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1) {
while ($stmt->fetch()) {
// echo data from table like $data["name"]; <----
}
}
else {
echo "Failed";
}
}
What I want to know is the equivalent of while($data=mysqli_fetch_assoc($result)) to replace my existing code (in OOP way) while ($stmt->fetch()) and make it fetch the datas using $data["name"]
You need to tell PHP in which variable(s) to store the result. There are two ways to do this:
with bind_result, and then fetch on the statement object, or
with get_result, and then fetch_assoc (or other fetch_* variant) on the result object
1. bind_result
With this solution you bind variable(s) to the SELECT list, and while looping with fetch PHP will put the new data in those variable(s):
$stmt = $this->conn->prepare("SELECT id FROM lms_admin_users WHERE email=?");
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $name); // <- Add; #args = #cols in SELECT
if($stmt->num_rows == 1) {
while ($stmt->fetch()) {
echo $id, $name; // <-- then you can do this.
}
}
2. get_result
Instead of bind_result you can use get_result, which will give a result object which you can fetch each row from as an associative array:
//...
// $stmt->store_result(); // <- Remove: does not work together with next statement
$result = $stmt->get_result(); // <--- add this instead
if($result->num_rows == 1) { // <--- change to $result->...!
while ($data = $result->fetch_assoc()) {
echo $data['id'], $data['name']; // <--- available in $data
}
}

correct way to check if user is found in mysql table

The function should return the id of the found user or return false if not found.
Currently I am using bind result and fetch to check if a user is found in an mysql table:
public function getUserIDByName($UserName) {
$uid = "";
$i=0;
if($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")){
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
while($stmt->fetch()){
$i++;
}
$stmt->close();
}
if($i==0){
return false;
}else{
return $uid;
}
}
This works, but I assume that there is a proper way to do this without a counter in the fetch loop. I can not use get_result as mysqlnd is not available.
Simple use num_rows to check your query return result or not
function getUserIDByName($UserName) {
if ($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")) {
$stmt->bind_param("s", $UserName);
$stmt->execute();
$row_cnt = $stmt->num_rows;
if ($row_cnt == 1) {
$stmt->bind_result($uid);
while ($stmt->fetch()) {
return $uid;
}
} else {
return false;
}
}
}
Use this instead
public function getUserIDByName($UserName)
{
$uid = '';
$response = false;
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?");
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
if ($stmt->fetch()) {
$response = $uid;
}
$stmt->close();
return $response;
}
EDIT: just realized you're using mysqli and not pdo. Ill leave this here if you want to use PDO in the feature I guess.
This is how I would do it. You could change rowcount() > 0 to rowcount() === 1 if you want to guarantee only 1 user is found.
public function getUserIDByName($UserName)
{
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name = :name");
// bind :name to the username
$stmt->bindParam(":name", $UserName);
// execute the query
$stmt->execute();
// check the rowcount
if ($stmt->rowcount() > 0) {
// fetch the results as a associative array
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// return false because rowcount wasn't bigger than 0
return false;
}

Count left attempts rows

I have this MYSQL Table :
id | action
A6bIMWP1rQ changedusername
A6bIMWP1rQ changedusername
Now how i make this php function to count if more then 5 times changedusername exsit, it will return false?
i have tryed:
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT action FROM userchange_attemps WHERE user_id = ?")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there has been more than 5 failed logins
if($stmt->num_rows > 5) {
return true;
}else{
return false;
}
}
}
And how with php i determine how much left attemps upto 5 ?
Lets say now in my table theres 2 rows, and left 3 , how i return that value to the user ?
Thanks.
Use mysql COUNT
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT COUNT(id) as count FROM userchange_attemps WHERE user_id = ? AND action = 'changedusername'")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
$row = $stmt->fetch_assoc();
if($row['count'] > 5) {
//do something
} else {
//do something else
}
}
}
How about...
SELECT COUNT(action)
FROM userchange_attemps
WHERE action = 'changedusername' AND user_id= ?

PHP Checking for item in database

I'm new to PHP and I am trying to check if a user exists in a MySQL database over a MySQLi connection. The name of the user I'm trying to check for is stored in a variable called $code. What would I insert into the statement below to get it to check for $code?
$stmt = $this->db->prepare("SELECT id_user FROM members WHERE username = ??? ($code)");
Thanks for your help.
Edit: Here is my code:
class RedeemAPI {
private $db;
// Constructor - open DB connection
function __construct() {
$this->db = new mysqli('localhost:3306', 'username', 'password', 'db');
$this->db->autocommit(FALSE);
}
// Destructor - close DB connection
function __destruct() {
$this->db->close();
}
// Main method to redeem a code
function redeem() {
// Check for required parameters
if (isset($_POST["username"])) {
// Put parameters into local variables
$code = $_POST["username"];
// Look up code in database
$id_user= 0;
$stmt = $this->db->prepare('SELECT id_user FROM members WHERE username = ?');
$stmt->bind_param("s", $code);
$stmt->execute();
$stmt->bind_result($id_user);
while ($stmt->fetch()) {
break;
}
$stmt->close();
// Bail if code doesn't exist
if ($id_user <= 0) {
sendResponse(400, 'Invalid code');
return false;
}
// Return username, encoded with JSON
$result = array("username" => $code);
sendResponse(200, json_encode($result));
return true;
}
sendResponse(400, 'Invalid request');
return false;
}
}
See mysqli_stmt::bind_param():
$stmt = $this->db->prepare("SELECT id_user FROM members WHERE username = ?");
$stmt->bindParam('s', $code);
$stmt->exeucte();
Here's a good example of a prepared statement:
if ($stmt = $mysqli->prepare("SELECT id_user FROM members WHERE username = ?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $code);
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($result);
/* fetch values */
while ($stmt->fetch()) {
$result = $result;
}
/* fetch value */
$stmt->fetch();
/* close statement */
$stmt->close();
}

Categories