can i use md5 hashed values inside $this->db->escape() in codeigniter, - php

when i tried to use md5 hashed values inside $this->db->escape() i'm getting error like below when i tried to fetch count of results
"Call to a member function num_rows() on bool"
my code
$hashedUniqueId= md5($uniqueId);
$query = "select * from my_table where uId_hash= '".$this->db->escape($hashedUniqueId)."' AND password= '".$this->db->escape($password)."' ";
$result = $this->db->query($query);
print_r($result->num_rows());

You are making double escape as i see it. Remove the single quotes from $this->db->escape().
$query = "select * from my_table where uId_hash= ".$this->db->escape($hashedUniqueId)." AND password= ".$this->db->escape($password);
Or the better way is to set the variables in the $this->db->query($query);
This way codeigniter will escape it for you.
$hashedUniqueId= md5( $uniqueId );
$query = "select * from my_table where uId_hash= ? AND password= ?";
$result = $this->db->query( $query, array( $hashedUniqueId, $password ) );
print_r($result->num_rows());

Related

Prepared Statements Mysql not working

I am trying to use prepared statements to select data from a table as the following. This method does not work.
$sql = "SELECT * FROM `usrs` WHERE `username` = ? ";
$statement = $this->conn->prepare($sql);
if (!statement)
{
throw new Exception($statement->error);
}
$statement->bind_param("s",$username);
$returnValue = $statement->execute();
return $returnValue;
$sql should be in the following format.
$sql = "SELECT * FROM `usrs` WHERE `username` = 'username' ";
however the above code does not place single quotes ' ' around username
I need to place username between two single quotes ' ' as shown. if I use just
$sql = "SELECT * FROM `usrs` WHERE `username` = username "
it does not work.
any suggesstions how to do that.
Read this carefully:
bool mysqli_stmt::execute ( void )
it means it returns boolean - that is not a usable object or an array.
You've to fetch the statement.
Here's the fix:
$sql = "SELECT * FROM `usrs` WHERE `username` = ? LIMIT 1";
$statement = $this->conn->prepare($sql);
$statement->bind_param("s",$username);
if ($statement->execute()) {
$result = $statement->get_result();
return $result->fetch_assoc();
}
return null;
P.S. Thank You #Phil for fixing my mistakes in my answer

This PDO prepare statement won't work *how do i fix*?

$checkUser1 = "SELECT * FROM users WHERE username='$username'";
$checkUser = $handler->prepare($checkUser1);
$checkUser->execute(array(':username' => $username));
$cU = ($checkUser->rowCount());
This won't work, I'm not really sure how I should fix it.
It's a PDO prepare statement.
This
$checkUser1 = "SELECT * FROM users WHERE username='$username'";
should be
$checkUser1 = "SELECT * FROM users WHERE username=:username";
This way you can bind the variable to the parameter like you are trying in your execute array.

Possible to have PHP MYSQL query ignore empty variable in WHERE clause?

Not sure how I can do this. Basically I have variables that are populated with a combobox and then passed on to form the filters for a MQSQL query via the where clause. What I need to do is allow the combo box to be left empty by the user and then have that variable ignored in the where clause. Is this possible?
i.e., from this code. Assume that the combobox that populates $value1 is left empty, is there any way to have this ignored and only the 2nd filter applied.
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Thanks for any help.
C
Use
$where = "WHERE user_id = '$username'";
if(!empty($value1)){
$where .= "and location = '$value1'";
}
if(!empty($value2 )){
$where .= "and english_name= '$value2 '";
}
$query = "SELECT * FROM moth_sightings $where";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Several other answers mention the risk of SQL injection, and a couple explicitly mention using prepared statements, but none of them explicitly show how you might do that, which might be a big ask for a beginner.
My current preferred method of solving this problem uses a MySQL "IF" statement to check whether the parameter in question is null/empty/0 (depending on type). If it is empty, then it compares the field value against itself ( WHERE field1=field1 always returns true). If the parameter is not empty/null/zero, the field value is compared against the parameter.
So here's an example using MySQLi prepared statements (assuming $mysqli is an already-instantiated mysqli object):
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = ?
AND location = IF(? = '', location, ?)
AND english_name = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssss', $username, $value1, $value1, $value2);
$stmt->execute();
(I'm assuming that $value2 is a string based on the field name, despite the lack of quotes in OP's example SQL.)
There is no way in MySQLi to bind the same parameter to multiple placeholders within the statement, so we have to explicitly bind $value1 twice. The advantage that MySQLi has in this case is the explicit typing of the parameter - if we pass in $value1 as a string, we know that we need to compare it against the empty string ''. If $value1 were an integer value, we could explicitly declare that like so:
$stmt->bind_param('siis', $username, $value1, $value1, $value2);
and compare it against 0 instead.
Here is a PDO example using named parameters, because I think they result in much more readable code with less counting:
$sql = "SELECT *
FROM moth_sightings
WHERE user_id = :user_id
AND location = IF(:location_id = '', location, :location_id)
AND english_name = :name";
$stmt = $pdo->prepare($sql);
$params = [
':user_id' => $username,
':location_id' => $value1,
':name' => $value2
];
$stmt->execute($params);
Note that with PDO named parameters, we can refer to :location_id multiple times in the query while only having to bind it once.
if ( isset($value1) )
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
else
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND english_name = $value2 ";
But, you can also make a function to return the query based on the inputs you have.
And also don't forget to escape your $values before generating the query.
1.) don't use the simply mysql php extension, use either the advanced mysqli extension or the much safer PDO / MDB2 wrappers.
2.) don't specify the full statement like that (apart from that you dont even encode and escape the values given...). Instead use something like this:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s", ...);
Then fill that raw query using an array holding all values you actually get from your form:
$clause=array(
'user_id="'.$username.'"',
'location="'.$value1.'"',
'english_name="'.$value2.'"'
);
You can manipulate this array in any way, for example testing for empty values or whatever. Now just implode the array to complete the raw question from above:
sprintf("SELECT * FROM moth_sightings WHERE 1=1 AND %s",
implode(' AND ', $clause) );
Big advantage: even if the clause array is completely empty the query syntax is valid.
First, please read about SQL Injections.
Second, $r = mysql_numrows($result) should be $r = mysql_num_rows($result);
You can use IF in MySQL, something like this:
SELECT * FROM moth_sightings WHERE user_id = '$username' AND IF('$value1'!='',location = '$value1',1) AND IF('$value2'!='',english_name = '$value2',1); -- BUT PLEASE READ ABOUT SQL Injections. Your code is not safe.
Sure,
$sql = "";
if(!empty($value1))
$sql = "AND location = '{$value1}' ";
if(!empty($value2))
$sql .= "AND english_name = '{$value2}'";
$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' {$sql} ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Be aware of sql injection and deprecation of mysql_*, use mysqli or PDO instead
I thought of two other ways to solve this:
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND location = '%$value1%'
AND english_name = $value2 ";
This will return results only for this user_id, where the location field contains $value1. If $value1 is empty, this will still return all rows for this user_id, blank or not.
OR
SELECT * FROM moth_sightings
WHERE
user_id = '$username'
AND (location = '$value1' OR location IS NULL OR location = '')
AND english_name = $value2 ";
This will give you all rows for this user_id that have $value1 for location or have blank values.

PHP Query failing, show error?

I have a query on my page that uses a GET variable to pull data from my table...
If I echo my GET var the data is there so im doing something wrong with my query, instead of or die can I show an error in the browser?
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = 'SELECT * FROM persons WHERE id = $userID';
$q = $conn->query($sql) or die('failed!');
$sql = "SELECT * FROM persons WHERE id = $userID";
You must use double quotes to use variables inside the query string.
You can also do this:
$sql = "SELECT * FROM persons WHERE id = ".$userID;
What you should do is this (to protect yourself from sql injection):
$safeuid = $conn->prepare($userID);
$sql = "SELECT * FROM persons WHERE id = ".$safeuid;
You can always debug using this at the top of your php page:
ini_set('display_errors',1);
error_reporting(E_ALL);
Have you tried $q = $conn->query($sql) or die($conn->error()); ?
Yes you can, but you should only do it for debugging. Crackers can gain a lot of insight by purposefully feeding bad input and reading the error.
I'm assuming you're using MySQLi; the command is $conn->error(). So your line would be:
$q = $conn->query($sql) or die($conn->error());
Also, what you're doing wrong is you're using single quotes to define $sql. You need to use double quotes to write $userID into the string. So what you want is:
$sql = "SELECT * FROM persons WHERE id = $userID";
or
$sql = 'SELECT * FROM persons WHERE id = ' . $userID;
You need to use double quotes to evaluate variables within the string. That is,
$sql = 'SELECT * FROM persons WHERE id = $userID';
should be
$sql = "SELECT * FROM persons WHERE id = $userID";
Rather than removing the die you should make sure the query is always valid. In other words: validate the userID parameter. $_GET can contain anything the user wants to provide - it could be an array, it could be a string, it could be a string with a malicious payload that can drop your tables. So check it is an integer. If not, return a relevant message to the user.
Not a php expert but you might try:
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = 'SELECT * FROM persons WHERE id = $userID';
$q = $conn->query($sql) or die('failed!' . mysql_error());
The error should append to the end of your die message.

Php function within SQL statement syntax

I have the following code. I would like username to take the value of the getUserName function however I am fighting with syntax. Can anybody tell me what should be the correct one?
$query = "SELECT user FROM users_entity WHERE username = getUserName()";
You can use concatenation with the period:
$query = "SELECT user FROM users_entity WHERE username = '".mysql_real_escape_string(getUserName())."'";
Make sure to escape your data!
You can't embed the result of a function directly into a string. However you can store the contents of a variable:
$username = mysql_real_escape_string(getUserName());
$query = "SELECT user FROM users_entity WHERE username = '$username'";
Or, you could concatenate your string like this:
$query = 'SELECT user FROM users_entity WHERE username = \'' . mysql_real_escape_string(getUserName()) . '\'';
You cannot interpolate (internally string-replace) PHP function names into strings.
You probably want something more like this:
$query = sprintf("SELECT user FROM users_entity WHERE username = '%s'"
mysql_real_escape_string(getUserName())
);
$query = "SELECT user FROM users_entity WHERE username = '".getUserName()."'";

Categories