Can I use my own functions from PHP directly in SQL queries (using mySQL and PDO)? For example:
$query = null;
$result = null;
$query = $this->database_0->prepare("SELECT `id`, `salt` FROM `general_users` WHERE `username` = :username AND `password` = CONCAT(generatePassword(:password, `salt`)) LIMIT 1");
$query->bindValue(':username', $this->input->getValue('username'), PDO::PARAM_STR);
$query->bindValue(':password', $this->input->getValue('password'), PDO::PARAM_STR);
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
$query->closeCursor();
Look at line 3 in "WHERE" case.
If it is not possible, I must use two queries just for check if a user exists, it do not look very optimal.
Thanks for your help, Bartek.
Can I use my own functions from PHP directly in SQL queries
No.
Mysql knows nothing of PHP and its functions. You are bound to use mysql functions in mysql and PHP functions in PHP. Quite easy to memorize.
So, here you go, with one single query
$sql = "SELECT id, salt, password FROM general_users WHERE username = ?";
$stmt = $this->db->prepare($sql);
$query->execute([$this->input->getValue('username')]);
$row = $query->fetch();
if (generatePassword($row['password'], $row['salt']) == $this->input->getValue('password'))
{
You can't use a PHP function in a MySQL query.
You can still do this with a single query. Just retrieve user info (including password) by comparing only its username. Then, in PHP, compare stored password with the one you have just computed. That would even allow you to distinguish two cases: "user exists, but password is wrong" and "user does not exist".
Related
This is my first time to try PDO and still learning it. I am more familiar in using mysql or mysqli in developing php system.
After deep searching and searching I still can't seem to understand how to query using PDO
In my code I used mysqli inside a function to be called in index.php
function getUsery(){
$ip = getIPAddress();
$query = mysqli_query("select userID from tblUsers where logged='1' AND ip='$ip'");
$row = mysqli_fetch_array($query);
$emp = $row['userID'];
$logged = $row['logged'];
$userlvl = $row['userLevel'];
$_SESSION['logged'] = $logged;
$_SESSION['userLevel'] = $userlvl;
return $emp;
}
I don't really know how to select sql query using PDO with 'where' statement. Most of what I found is using array with no 'where' statement
How can I select the userID where logged is equal to '1' and ip is equal to the computer's ip address and return and display the result to the index.php
There's SQL statement with WHERE in PDO
$sql = "SELECT * FROM Users
WHERE userID = ?";
$result = $pdo->prepare($sql);
$result->execute([$id]);
Assuming that you know how to connect database using PDO, here is how to select SQL with PDO.
$stmt = $db->prepare("select userID from tblUsers where logged = '1' AND ip = :ip");
$stmt->execute(array('ip' => $ip));
$listArray = $stmt->fetchAll();
Notice the :ip at the end of SELECT. If you don't use ? as a parameters, the prefix : is mandatory and the word after that should be the same as the key in the execute function.
EDIT
In case that the above code is inside the function and $db is outside the function, declare $db as global variable inside the function.
This one is imo one of best guides on PDO and how to use it:
https://phpdelusions.net/pdo
WHERE is a part of query and queries in PDO are not much different from pure *sql queries, just there is going on a bit filtering on execution. Read the guide carefully and you will be able to execute any query you need to.
I have a MySQL query which works from the command line, but not from PHP.
Can anyone see what I am doing wrong?
$sqlText = 'SELECT FROM customers WHERE login_name=:name
AND password=:password';
$query = $pdo->prepare($sqlText);
$query->bindParam(':name', $userName);
$query->bindParam(':password', sha1($password));
$result = $query->fetch(PDO::FETCH_ASSOC);
and $result is false.
But, from the command line,
SELECT * FROM customers WHERE login_name="a"
AND password="4192dee2f886e99ececbb2eee0d2f37f11257974"
works.
When I debug userName is a and $password is 4192dee2f886e99ececbb2eee0d2f37f11257974.
Can some one make me say D'oh ?
You've forgotten about execute I suppose:
$sqlText = 'SELECT FROM customers WHERE login_name=:name AND password=:password';
$query = $pdo->prepare($sqlText);
$hash = sha1($password);
$query->bindParam(':name', $userName);
$query->bindParam(':password', $hash);
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
You forgot execute().
Moreover, if really $password` is `4192dee2f886e99ececbb2eee0d2f37f11257974, then you must be running sha1() twice. Either remove the sha1() from the bind line, or keep $password in the clear.
I'd suggest naming the database column "passwordHash", and the variable either $password if it is in cleartext, or $passwordHash if you already ran sha1() on it. That way, you would have written
$query->bindParam(':passwordHash', sha1($passwordHash));
and immediately spotted the extra sha1() call.
you have to call $query->execute(); to execute the query in PDO
$sqlText = 'SELECT FROM customers WHERE login_name=:name AND password=:password';
$query = $pdo->prepare($sqlText);
$query->bindParam(':name', $userName);
$query->bindParam(':password', sha1($password));
$query->execute();
$result = $query->fetch(PDO::FETCH_ASSOC);
The prepare method only prepares the sql statement you passed in and returns a preparedstatement object.
As mentioned above, you need to set the params and execute it to get the resultset back.
The advantages of prepared statement besides the security is that you can repeatedly assign parameters and execute a preparedstatement which is considered to be faster than compiling the same sql query string again and again.
My question supposed to be simple! although, I couldn't find the correct answer!
I need to retrieve the "hashed password" for the giving "username" from mySql database with php, then I need to store it in a variable, how could I do that?
All what I get is "Resource id #5"!
This is my code:
$query = "SELECT hashed_password ";
$query .= "FROM users ";
$query .= "WHERE username = '{$username}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "LIMIT 1";
$result_set = mysql_query($query);
echo "$result_set";
echo '</br>';
To start off, let's use a MySQL library that supports prepared statements - otherwise, we'll run into SQL Injection issues in the future. Now, back to the actual question / answer.
If we use MySQLi, we have a few functions that will help us. Here's an example of an answer to your question w/ code comments to help walk through it:
// create our db connection
$mysqli = new mysqli('localhost', 'db_username', 'db_password', 'db_table');
// create a Prepared Statement to query to db
$stmt = $mysqli->prepare('SELECT hashed_password FROM users WHERE username = ? LIMIT 1');
// dynamically bind the supplied "username" value
$stmt->bind_param('s', $username);
// execute the query
$stmt->execute();
// get the first result and store the first column in the `$hashed_password` variable
$stmt->bind_result($hashed_password);
$stmt->fetch();
// close our Prepared Statement and the db connection
$stmt->close();
$mysqli->close();
echo $hashed_password;
Check out the PHP Doc for mysqli::prepare() for more examples =]
Note: I highly recommend avoiding the mysql_query() (and family) functions. They are not only deprecated, but they are quite insecure to use.
You need to fetch the data out of the mysql-resource that is returned by a query.
Just pass it through mysql_fetch_assoc($result_set). It will return your data in a nice and ordered arraay, moving ahead one row every call.
Meaning you can do
while ($row = mysql_fetch_assoc($result_set).
Also, please use mysqli. Its basically the same just with mysqli instead of mysql in commands. See the docs here for more info: http://php.net/manual/en/book.mysqli.php
I am new to PHP and have a really basic question.
If I know the result of a query is only a single value (cell) from a single row in MySQL how can I simplify the below without having to go through an array of results and without increasing the risk of SQL injection ?
In the example below I would just need to echo a single email as the result of the query.
I found a couple of posts suggesting different approaches with fetch_field for this but I am not sure what is the best way here since some of these seem to be pretty old or deprecated now.
My PHP:
$stmt = $conn->prepare("SELECT email FROM Users WHERE userName = ? LIMIT 1");
$stmt->bind_param('s', $userName);
$stmt->execute();
$result = $stmt->get_result();
$arr = $result->fetch_assoc();
echo $arr["email"];
Many thanks in advance.
You can avoid caring what the column is called by just doing this:
<?php
$stmt = $conn->prepare("SELECT email FROM Users WHERE userName = ? LIMIT 1");
$stmt->bind_param('s', $userName);
$stmt->execute();
$email = $stmt->get_result()->fetch_object()->email;
echo $email;
I have this code for selecting fname from the latest record on the user table.
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$sdt=$mysqli->('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$sdt->bind_result($code);
$sdt->fetch();
echo $code ;
I used prepared statement with bind_param earlier, but for now in the above code for first time I want to use prepared statement without binding parameters and I do not know how to select from table without using bind_param(). How to do that?
If, like in your case, there is nothing to bind, then just use query()
$res = $mysqli->query('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$fname = $res->fetch_row()[0] ?? false;
But if even a single variable is going to be used in the query, then you must substitute it with a placeholder and therefore prepare your query.
However, in 2022 and beyond, (starting PHP 8.1) you can indeed skip bind_param even for a prepared query, sending variables directly to execute(), in the form of array:
$query = "SELECT * FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->execute([$_POST['ID']]);
$result = $stmt->get_result();
$row = $result->fetch_assoc();
The answer ticked is open to SQL injection. What is the point of using a prepared statement and not correctly preparing the data. You should never just put a string in the query line. The point of a prepared statement is that it is prepared. Here is one example
$query = "SELECT `Customer_ID`,`CompanyName` FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->bind_param('i',$_POST['ID']);
$stmt->execute();
$stmt->bind_result($id,$CompanyName);
In Raffi's code you should do this
$bla = $_POST['something'];
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$stmt = $mysqli->prepare("SELECT `fname` FROM `user` WHERE `bla` = ? ORDER BY `id` DESC LIMIT 1");
$stmt->bind_param('s',$_POST['something']);
$stmt->execute();
$stmt->bind_result($code);
$stmt->fetch();
echo $code;
Please be aware I don't know if your post data is a string or an integer. If it was an integer you would put
$stmt->bind_param('i',$_POST['something']);
instead. I know you were saying without bind param, but trust me that is really really bad if you are taking in input from a page, and not preparing it correctly first.