I'm switching from MySQL to PDO and I'm unsure if this query is correct.. would I still be required to write the if command.
public function User_Login($_iUsername,$_iPassword) {
$username=mysql_real_escape_string($_iUsername);
$password=mysql_real_escape_string($password);
$md5_password=md5($_iPassword);
$query=mysql_query("SELECT _iD FROM users WHERE _iUsername='$_iUsername' and _iPassword='$md5_password' AND _iStatus='1'");
if( mysql_num_rows( $query ) == 1 ) {
$row = mysql_fetch_array( $query );
return $row['_iD'];
} else {
return false;
}
}
TO
public function User_Login($_iUsername,$_iPassword) {
$md5_password = md5($_iPassword);
$sth = $db->prepare("SELECT _iD FROM users WHERE _iUsername='$_iUsername' and _iPassword='$md5_password' AND _iStatus='1'");
$sth->execute();
$result = $sth->fetchAll();
}
First off, you're not properly parameterizing the query. It's great that you're using PDO, but one of the main purposes of the change is the ability to parameterize queries. Secondly, md5 is a very weak hash. I suggest using bcrypt instead. Finally, PDOStatement::rowCount is the method you are looking for.
$sth = $db->prepare("SELECT _ID FROM users WHERE _iUsername = ?
AND _iPassword = ? AND _iStatus = 1");
$sth->execute(array($_iUsername, $md5_password));
if ($sth->rowCount() == 1) {
$row = $sth->fetch(PDO::FETCH_ASSOC);
return $row['_iD'];
}
else {
return false;
}
Related
I need help with converting this SQL to Prepared Statement. This is for my search bar. I hope I'll be able to receive some help as I am a beginner in this.
This is my SQL
$conn = mysqli_connect('localhost','root','','my_db');
$mysql = "SELECT * FROM catetable";
$bike_list = mysqli_query($conn,$mysql);
$catesql = "SELECT catename FROM catetable";
$cate_list = mysqli_query($conn,$catesql);
And this is what I would like to change to Prepared Statement
if (isset($_GET['search']))
{
$search = $_GET['search'];
$searchlist = array();
$lowersearchlist = array();
$i = 0;
while ($one_cate = mysqli_fetch_assoc($cate_list))
{
$searchlist[$i] = $one_cate['catename'];
$lowersearchlist[$i] = strtolower($one_cate['catename']);
$i++;
}
if (in_array($search,$searchlist) || in_array($search,$lowersearchlist))
{
header("Location:feature.php");
}
else
{
header("Location:index.php?error=true");
}
}
Write a query that matches the parameter in the WHERE clause. MySQL normally defaults to case-insensitive comparisons, so you don't need to fetch all the rows to compare them exactly and case-insensitively.
if (isset($_GET['search'])) {
$stmt = $conn->prepare("SELECT COUNT(*) AS c FROM yourTable WHERE catename = ?");
$stmt->bind_param("s", $_GET['search']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if ($row['c'] > 0) {
header("Location: feature.php");
} else {
header("Location: index.php?error=true";
}
}
I have a question related to php / pdo and sqlite. I have ported some code from a mysql backend to a sqlite backend. I have used rowCount() alot in this project.
In my original Mysql application i did this:
$stmt = $db->query("SELECT id FROM table where id = $id ");
$rc = $stmt->rowCount();
if ($rc == 1) {
// do something
}
The documentation says this method is only for returning affected rows from UPDATE, INSERT, DELETE queries, with the PDO_MYSQL driver (and this driver only) you can get the row count for SELECT queries.
So, how to achive the same thing with a sqlite backend?
This is how I have ended up doing it:
$stmt = $db->query("SELECT count(id) as cnt FROM table where id = $id ");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($row['cnt'] == "1") {
// do something
} else {
return false;
}
}
}
I am looking for a more elegant solution, while achieving the same thing as rowCount().
This is the way to do that in pdo:
$stmt = $db->query('SELECT * FROM table');
if ($stmt->rowCount() == 1) {
//...
} else {
//...
}
echo $row_count.' rows selected';
(The same way XD)
BTW, I wouldn't recommend doing something like
$stmt = $db->query("SELECT count(id) as cnt FROM table where id = $id ");
It's not good to have variables in statements like that. use something like:
$stmt = $db->query('SELECT id FROM table where id = ?');
$stmt->execute(array($id));
if ($stmt->rowCount() == 1)
{
$arr = $stmt->fetch(PDO::FETCH_ASSOC);
foreach($arr as $element)
{
echo '<pre>'.print_r($element).'</pre>';
}
}
else
{
//...
}
This is part of some code I'm using:
$stmt = $db->prepare('SELECT * FROM users WHERE id=?');
$stmt->execute(array($id));
if ($stmt->rowCount() == 1) {
$currentUser = $stmt->fetchAll(PDO::FETCH_ASSOC)[0];
} else {
return false;
}
Edit: (for compatibility issues)
$stmt = $db->query('SELECT * FROM table');
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (($arr === false) || (sizeof($arr) == 0)) {
return false;
} else {
//... do ....
echo sizeof($arr);
}
Below is the function I am using. It is strange because when I test the name "admin" it returns an associative array with all the correct columns and values, however every other name tests returns 0 as far as I can tell, meaning nothing is found from the query (I am entering the names perfectly as they are in the database).
I have a feeling this could be some sort of security feature of pdo or something but I don't understand why it is acting up this way.
I am using mysql.
Does anyone know the problem and how to resolve it? Thank you!
function getUserDetailsByName($name, $fields = "*")
{
$db = connect_db();
$query = "SELECT $fields FROM UserDetails WHERE userName=:username";
$result = $db->prepare($query);
$result->bindParam(":username", $name);
if (!($result->execute())) {
sendMessage (1,1,'Query failed',$query);
$db = null;
return;
}
if (!($result->fetch(PDO::FETCH_NUM) > 0)) {
$db = null;
return 0;
}else{
$result = $result->fetch();
$db = null;
return $result;
}
}
EDIT: Someone asked to post how I call the function.
$user = getUserDetailsByName($_POST['value']);
if($user == 0)
{
print "user = 0";
}
print_r($user);
function getUserDetailsByName($name, $fields = "*"){
$db = connect_db();
$query = "SELECT {$fields} FROM UserDetails WHERE userName = :username LIMIT 1;";
if(!$result = $db->prepare($query)){
return null;
}
$result->bindParam(":username", $name);
if(!$result->execute()) {
sendMessage (1,1,'Query failed',$query);
return null;
}
if(!$user = $result->fetch(PDO::FETCH_NUM)) {
return false;
}
return $user;
}
Why 2 fetches? Checkout and compare this to your code.
Use like this:
if($user = getUserDetailsByName($_POST['value'])){
// we have a user!
}else{
// we don't have a user!
}
I'm 'doomsday' (mysql_ depreciation!) prepping some of my older applications that take the use of mysql_ extentions. I am currently converting them into PDO.
I use a lot of functions to make my work easy. However I cant get the $db->query within a function to work. For example I'm converting this function:
function GetAccount($account_id){
$Query = mysql_query("SELECT name, balance, account_number FROM accounts WHERE id = '$account_id'");
if (mysql_num_rows($Query) > 0){
$Result = mysql_fetch_assoc($Query);
return $Result;
} else {
return false;
}
}
Into this PDO function.
function GetAccount($account_id){
global $db;
$Result = $db->query("SELECT name, balance, account_number FROM accounts WHERE id = '$account_id'");
if (count($Result) > 0){
return $Result;
} else {
return false;
}
}
I have established a PDO connection outside of this function, which works fine with queries outside of any function.
The problem for the second (PDO) function is that the $Result is empty. A var_dump returs: bool (false).
What am I forgetting/doing wrong?
Thank you :)
Fixed it, new function:
function GetAccount($account_id){
global $db;
$Result = $db->prepare("SELECT name, balance, account_number FROM accounts WHERE id = '$account_id'");
$Result->execute();
$Result = $Result->fetch();
if (count($Result) > 0){
return $Result;
} else {
return false;
}
}
The only thing I did was :
$Result->prepare("query stuff");
$Result->execute();
$Result = $Result->fetch();
This is the login function written using MySQL way
However, the problem exists when it convert into PDO way
MYSQL:
<?
function confirmUser($username, $password){
global $conn;
if(!get_magic_quotes_gpc()) {
$username = addslashes($username);
}
/* Verify that user is in database */
$q = "select UserID,UserPW from user where UserID = '$username'";
$result = mysql_query($q,$conn);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}
/* Retrieve password from result, strip slashes */
$dbarray = mysql_fetch_array($result);
$dbarray['UserPW'] = stripslashes($dbarray['UserPW']);
$password = stripslashes($password);
/* Validate that password is correct */
if($password == $dbarray['UserPW']){
return 0; //Success! Username and password confirmed
}
else{
return 2; //Indicates password failure
}
}
PDO:
<?
function confirmUser($username, $password){
global $conn;
include("connection/conn.php");
$sql = '
SELECT COALESCE(id,0) is_row
FROM user
WHERE UserID = ?
LIMIT 1
';
$stmt = $conn->prepare($sql);
$stmt->execute(array('09185346d'));
$row = $stmt->fetch();
if ($row[0] > 0) {
$sql = '
SELECT COALESCE(id,1) is_row
FROM user
WHERE UserPW = ?
LIMIT 1
';
$stmt = $conn->prepare($sql);
$stmt->execute(array('asdasdsa'));
$row = $stmt->fetch();
if ($row[0] > 0)
return 2;
else
return 0;
}
elseif ($row[0] = 0)
{return 1;}
}
What is the problem ?? And is it necessary to include bind parameter in PDO??? THANKS
Aside from your use of global and your include inside the function (you should investigate an alternative way of structuring your function not to do this), I would change the code as follows:
$sql =
'SELECT id
FROM user
WHERE UserID = ?
AND UserPW = ?
LIMIT 1';
$stmt = $conn->prepare($sql);
$stmt->execute(array(
'09185346d',
'asdasdsa'
));
if ($stmt->rowCount() == 1) {
return 0;
}
else {
return 1;
}
Combing the queries to give a general Authentication error, instead of allowing people to trial valid usernames, and then valid passwords, and then using PDOStatements rowCount method do see if your row was returned.
To answer your second part, it is not necessary to specifically use bindParam to prevent SQL injection.
Here's a quick example of the difference between bindParam and bindValue
$param = 1;
$sql = 'SELECT id FROM myTable WHERE myValue = :param';
$stmt = $conn->prepare($sql);
Using bindParam
$stmt->bindParam(':param', $param);
$param = 2;
$stmt->execute();
SELECT id FROM myTable WHERE myValue = '2'
Using bindValue
$stmt->bindValue(':param', $param);
$param = 2;
$stmt->execute();
SELECT id FROM myTable WHERE myValue = '1'