ive tried in vain for a good amount of time to convert this string from mysql to mysqli with no luck. here is what i had for mysql :
function user_exists($username) {
$username = sanitize($username);
$query = mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username'");
return (mysql_result($query, 0) == 1) ? true : false;
}
ive tried:
function user_exists($username) {
$link = mysqli_connect("localhost", "username", "password", "table");
$username = sanitize($username);
$usernamequery = "SELECT COUNT(`userid`) FROM `table` WHERE `username` = '$username' ";
$query = mysqli_query($link, $usernamequery);
$queryarray = mysqli_fetch_array($query, MYSQLI_BOTH);
$queryarrayres = mysqli_num_rows($query) ;
if ($queryarrayres > 0) { true; } else { false;}
}
numerous hits of this issue on here from previous users but none of them seem to work for me.this and this for example. it all seems fine until i get to converting the mysql_result query and it goes to pieces. i understand that mysql_result in the above situation is essentially checking to see if theres one row selected and thats it equal to one, ie present, but i just cant seem to get something equivalent in the mysqli.
function login($username, $password) {
$link = mysqli_connect("localhost", "username", "pw", "db");
$username = sanitize($username);
$password = md5($password);
$loginquery = "SELECT COUNT(`user_id`) FROM `users` WHERE `username` = $username AND `password` = $password";
$query = mysqli_query($link, $loginquery);
$queryarray = mysqli_fetch_array($query);
$queryarrayres = $queryarray[0];
return ($queryarrayres > 0)? $userid :false;
}
in this instance, $queryarrayres prints as 1 at the right occasion, and zero the rest. so that bit works. the function actually contains a password element too, which ive added.
unfortunately when i use the function is continually returns false. i have tested on a test page, and if i change $username and $password to absolute variable its seems to work. the code is identical between the old version (not shown), and this version, aside from the obvious mysqli updates. this narrows the issue down to three possibilities. 1) something to do with $username and $password population. 2) the $usernamequery string. 3) the return of the function. i reckon its three given that no other code has changed, but i cant put my finger on whats going on here.
Use this function below, it works
function user_id_from_username ($username){
global $connect;
$username = sanitize($username);
$query = " SELECT user_id FROM users WHERE username = '$username' ";
$result = mysqli_query($connect, $query);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo $row["user_id"];
}
Your new user_exists function is not returning anything.
change
if ($queryarrayres > 0) { true; } else { false;}
to
return ($queryarrayres > 0)?true:false;
You may use the following function and call the function
function mysqli_result($res, $row, $field=0) {
$res->data_seek($row);
$datarow = $res->fetch_array();
return $datarow[$field];
}
Related
I'm really new to php and been following a tutorial on youtube by php academy. Basically it's a script(s) that allows for login,registering and a remember me option, the tutorial is 2 years old so I tried to change some of the mysql functions to mysqli but I'm running into some problems..when I enter a username and hit login I get a "mysql_num_rows() expects parameter 1 to be resource, string given in user.php line 9" error and my if statement says "cannot find username try registering" but it should show "exists" because the username I entered is in fact in the database..I'm puzzled, also please forgive me if the script isn't the most secure, I know things should be escaped and such, your help would be appreciated
User.php :
<?php
function user_exists($username)
{
$username=$username;
$query = ("SELECT count(`user_id`) FROM `users` WHERE `username`='$username'");
if(mysql_num_rows($query)===1)
{return true;
} else{
return false;
}
}
?>
login.php
<?php
include ('core/init.php');
if(user_exists('drellen')===true){
echo "exists";
}
if(empty($_POST)===false){
$username=$_POST['username'];
$password=$_POST['password'];
if(empty($username) === true|| empty($password)=== true)
{
echo $error[]="Enter a username and password";
}
else if (user_exists($username)===false)
{
echo $error[]="Cannot find username try registering";
}
}
please note that the init.php has users.php included in it*****
Might have a mixture of the old mysql and the new mysqli functions mixed in, help making it full mysqli would be appreciated
You have not used mysql_query() to run query. How you get number of rows without it.
Note -> You should use mysqli_* functions instead of mysql_*
$query = mysqli_query("SELECT count(`user_id`) FROM `users` WHERE `username`='$username'");
//$row = mysqli_fetch_array($query);
$count = mysqli_num_rows($query);
you can try this
function user_exists($username)
{
$result = mysql_query("SELECT `user_id` FROM `users` WHERE `username`='$username' LIMIT 1 ") or die(mysql_error());
if($row = mysql_fetch_assoc($result))
{
return true;
}
else
{
return false;
}
}
Note : mysql_* is deprecated. use mysqli_* or PDO
UPDATE 2:
function user_exists($username)
{
global $your_db_conn;
$sql = "SELECT `user_id` FROM `users` WHERE `username`='$username' LIMIT 1 ";
$result = mysql_query($sql, $your_db_conn) or die(mysql_error());
if($row = mysql_fetch_assoc($result))
{
return true;
}
else
{
return false;
}
}
Here is a working example
After doing some digging around i found that the most important part in this new function is calling the global $db, and for sanitizing adding the $db, $data as well as in the query. if you look up other basic exampels of using mysqli_query($db, $sql); you will catch onto this quite easily
<?php
$db = mysqli_connect('localhost', 'root', 'password', 'database');
function sanitize($data) {
global $db;
return mysqli_real_escape_string($db, $data);
}
function user_exists($username)
{
global $db;
$username = sanitize($username);
$sql = "SELECT `id` FROM `Users` WHERE `username`='$username' LIMIT 1";
$result = mysqli_query($db, $sql) or die('query');
if($row = mysqli_fetch_assoc($result))
{
return true;
}
else
{
return false;
}
}
?>
<h1>test</h1>
<?php
if (user_exists('admin') === true){
echo "Good news, this exists";
} else {
echo "no good";
}
?>
So I have created a function:
function user_data($user_id) {
$data = array();
$user_id = (int)$unser_id;
$func_num_args = func_num_args();
$func_get_args = func_get_args();
if ($func_num_args > 1){
unset($func_get_args[0]);
$fields = '`' . implode('`, `', $func_get_args) . '`';
$data = mysql_fetch_assoc(mysql_query("SELECT $fields FROM `users` WHERE 'user_id' = $user_id"));
return $data;
}
}
By mistake I crated a typo unser_id but didnt relise up until I had to troubleshoot further along the line in my code.
I am creating a login script but the point in which I am having to troubleshoot is showing profile data from my other users.
The reason I point out the typo part is because it for some reason is a strange error. If I change it to user_id it will not allow me to login anymore. If I leave it as under_id it works.
I am having to troubleshoot because I believe this is the cause of the problem I am having trying to view other users profiles and showing their information and not mine which is happening right now.
For example, in my url www.mywebsite.com/myprofile shows my username and my email address, if I type in www.mywebsite.com/otherprofile it still shows my information. But it does show a query if I type a user that does not exist in my database so that part works.
I believe the issue all stems form this typo but am really stuck as to appraoch a resolve?
So here is the other code:
profile page:
if (isset($_GET['username']) === true && empty ($_GET['username']) === false) {
$username = $_GET['username'];
if (user_exists($username) === true) {
$user_id = user_id_from_username($username);
$profile_data = user_data($user_id, 'first_name', 'last_name', 'email');
?>
<p><?php echo $profile_data['profile']; ?></p>
<h1><?php echo $profile_data['first_name']; ?> profile</h1>
<p><?php echo $profile_data['email'] ?></p>
<?php
} else {
echo 'Sorry, that user does not exist';
}
} else {
header('Location: index.php');
exit();
}
Here all the related functions:
function logged_in(){
return (isset($_SESSION['user_id'])) ? true : false;
}
function user_exists($username) {
$username = sanitize($username);
$query = mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username'");
return (mysql_result($query, 0) == 1) ? true : false;
}
function email_exists($email) {
$email = sanitize($email);
$query = mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `email` = '$email'");
return (mysql_result($query, 0) == 1) ? true : false;
}
function user_active($username) {
$username = sanitize($username);
$query = mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username' AND `active` = 1");
return (mysql_result($query, 0) == 1) ? true : false;
}
function user_id_from_username($username) {
$username = sanitize($username);
return mysql_result(mysql_query("SELECT `user_id` FROM `users` WHERE `username` = '$username'"), 0, 'user_id');
}
function login($username, $password) {
$user_id = user_id_from_username($username);
$username = sanitize($username);
$password = md5($password);
return (mysql_result(mysql_query("SELECT COUNT(`user_id`) FROM `users` WHERE `username` = '$username' AND `password` = '$password' "), 0) == 1) ? $user_id : false;
}
The problem in your first function is that you are quoting your column name with single quotes:
$data = mysql_fetch_assoc(mysql_query("SELECT $fields FROM `users` WHERE 'user_id' = $user_id"));
^ ^
That means that you are not actually using the column user_id but a string.
You should change that to:
$data = mysql_fetch_assoc(mysql_query("SELECT $fields FROM `users` WHERE `user_id` = $user_id"));
(or without the backticks...).
Apart from that you are using the deprecated mysql_* functions and you don't have any error handling. You should switch to PDO or mysqli using prepared statements and make sure it throws exceptions (both can) so that you know exactly what goes wrong.
You are replacing the argument $user_id passed to user_data by $unser_id:
$user_id = (int)$unser_id;
This way, the value of $user_id will always be whatever is stored in $unser_id, not what is passed to the function. You should try removing the line, so the code actually uses the user id you are passing it.
If you do not have any variable called $unser_id you should check the PHP error logs. I suspect there will be lines saying something like Undefined variable: unser_id.
Can anyone please help me with the following error. I am making a register and login function for my website. I have it connected to my local database and in there I have created a user. When I test that I can login and that username and password is recognised, it works as expected. But I get this error
Warning: mysql_result(): Unable to jump to row 0 on MySQL result index 17 in C:\xampp\htdocs\LoginAndRegistration\core\functions\users.php on line 34
And this is what I have on line 34
return (mysql_result(mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'"), 0) == 1) ? true : false;
Which is part of the following function
function login($username, $password) {
$user_id = user_id_from_username($username);
$username = sanitize($username);
$password = md5($password);
return (mysql_result(mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'"), 0) == 1) ? true : false;
}
Ive been staring at it for ages now but cant seem to figure out the problem. Can anyone tell me what I am doing wrong?
Thanks
That line of code looks like that you want to check does username and password exist. You need to change your code to this:
return (mysql_result(mysql_query("SELECT COUNT(id) FROM users WHERE username = '$username' AND password = '$password'"), 0) == 1) ? true : false;
Also change (id) to your id name of column.
This error means the query failed. Always check if the query succeeded:
$q = mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'");
if ($q) {
if ($rows = mysql_num_rows($q)) {
// Continue operation, or set a flag
} else {
// No matching rows, throw an Exception or set a flag
}
} else {
// Something is wrong
die(mysql_error());
}
Your error probably comes from the fact that the query did not return any result at all because there was none with matching username and password.
I would really not stuff that much functions into each other. It looks overcomplicates, it does not leave any room to add error handling (like handling the case that is supposed to happen in your case), and it messes up PHP'S error reporting, because any error happening will be on the same code line.
Spread stuff out into multiple lines. It makes things clearer for you any anybody that reads your code, in enhances debugging activities, and is generally a good idea because of the lower line length.
You are getting a warning (not an error) because mysql_query at some times, it won't return any rows, so trying to get the first row with mysql_result when there are not rows, will raise the warning.
You can try:
function login($username, $password) {
$user_id = user_id_from_username($username);
$username = sanitize($username);
$password = md5($password);
$query = mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'");
if (mysql_num_rows($query) > 0)
return true;
else
return false;
}
With the depreciation argument aside, use mysql_num_rows instead of mysql_result.
function login($username, $password) {
$user_id = user_id_from_username($username);
$username = sanitize($username);
$password = md5($password);
return (mysql_num_rows(mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'")) == 1) ? true : false;
}
try this
function login($username, $password) {
$user_id = user_id_from_username($username);
$username = sanitize($username);
$password = md5($password);
$query = mysql_query("SELECT * FROM users WHERE username = '$username' AND password = '$password'") ;
if (mysql_num_rows($query) > 0 ) {
$data = true ;
}else {
$data = false ;
}
return $data ;
}
I have a while loop that goes through the rows returned from an SQL query. The values of a particular column from that row are stored in an array. The array is then iterated through and each element is compared with the input from the user. If the input matches an array element then a boolean becomes true. I'm trying to do this so that the user can enter a password to access a particular page. However it just doesn't work. I have printed all of the values from the array as well as the input, so I know that there isn't a problem there. But for some reason, the if statement just doesn't compare them. Here is the code:
if (isset( $_POST['ok'])) {
$password = $_POST['pass'];
$matched = false;
$pw = array();
mysql_connect("localhost", "xxx", "xxx")or die("Error");
mysql_select_db("details")or die("Error");
$query="SELECT * FROM members";
$result=mysql_query($query);
while ($row = mysql_fetch_assoc($result) ){
$pw[] = $row["pass"];
}
foreach($pw as $p){
if(strcmp($p, $password) == 0){
$matched = true;
}
}
if ($matched==true) {
//Membership page
} else {
//Error message
}
} else {
....
It would be much easier and efficient to change your query to something like this
$dbh = mysql_connect("localhost", "xxx", "xxx") or die("Error");
mysql_select_db("details", $dbh ) or die("Error");
$pass = mysql_real_escape_string( $_POST['pass'], $dbh );
$user = mysql_real_escape_string( $_POST['user'], $dbh );
$sqlQuery = <<< EOQ
SELECT
*
FROM
`members`
WHERE
`user` COLLATE utf8_bin = '{$user}' COLLATE utf8_bin
AND
`password` COLLATE utf8_bin = '{$pass}' COLLATE utf8_bin
EOQ;
$result = mysql_query( $sqlQuery );
if ( $result and ( mysql_num_rows( $result ) === 1 ) {
echo "success";
$userDetails = mysql_fetch_assoc( $result );
} else {
echo "username or password wrong";
}
Edit: updated the password and username check to be case sensitive in any case
Edit2: above comments remind not to store passwords plaintext. To change to hashed passwords
UPDATE members SET pass = SHA1( pass );
Then change your check to
... AND pass = SHA1( '{$pass}' )
You need a break after finding a match so that $matched will be equal to true.
if ( isset( $_POST['ok'] ) ) {
$password = $_POST['pass'];
$matched = false;
$pw = array();
mysql_connect("localhost", "xxx", "xxx")or die("Error");
mysql_select_db("details")or die("Error");
$query="SELECT * FROM members";
$result=mysql_query($query);
while ($row = mysql_fetch_assoc($result) ){
$pw[] = $row["pass"];
}
foreach($pw as $p){
if(strcmp($p, $password) == 0){
$matched = true; // found match so break out and do the membership.
break;
}
}
if ($matched==true) {
//Memebrship page
} else {
//Error message
}
} else {
....
Sugestions:
1) Replace the direct mysql function calls with PDO: ( this will not require any escaping, since the PDO will handle everything )
$mysql_host = "localhost";
$mysql_user = "xxx";
$mysql_password = "xxx";
$mysql_database = "details";
$dbLink = new PDO("mysql:host=$mysql_host;dbname=$mysql_database;charset=utf8", $mysql_user, $mysql_password, array(PDO::ATTR_PERSISTENT => true));
$query = db()->prepare("select * from members WHERE pass = ? limit 1");
$query->execute(array($_POST['pass']));
$query->setFetchMode(PDO::FETCH_ASSOC);
$myMember = $query->fetch();
$query->closeCursor();
2) If you want to stick with your code, you could use $pwd = mysql_real_escape_string($_POSt['pass']) for the posted password and then select the row containing the escaped received password $pwd. Also, do not forget mysql_free_result($result);!!!
3) Make a hash of the password therefore you will not need to use mysql_real_escape_string. use $pwHash = md5($_POST['pass']) or $pwHash = sha1($_POST['pass']) or any combination.
4) Please align your code. It will make it more readable for people answering your questions (offering help) and also for future maintenance (you or someone else; believe me, you`ll forget the code in 2-3 years).
5) Your code should work, I'm not sure why it doesn't. Try adding var_dump for $pw and also write something on the screen when the password matches. Maybe you swapped the pages (members with error)
Why the foreach loop ? You can do it like this:
if (isset( $_POST['ok'])) {
$password = $_POST['pass'];
$matched = false;
$pw = array();
mysql_connect("localhost", "xxx", "xxx")or die("Error");
mysql_select_db("details")or die("Error");
$query="SELECT * FROM members";
$result=mysql_query($query);
while ($row = mysql_fetch_assoc($result) ){
$pw[] = $row["pass"];
}
$pw_tmp = flip_array($pw);
if(isset($pw_tmp[$password])){
//Membership page
}else{
//Error message
}
}else{
// something else ...
}
I've been modifying a user authentication system and I'm having trouble setting a session for the admin. The reguser session is setting just fine, but I can't figure out why admin won't set.
A user with a userlevel of 9 is an admin. Yes, I know how to protect against SQL injection. I'm just trying to keep it as simple and easy to read for now. This probably won't get used for anything, I'm just getting some experience with PHP.
Hi everyone, thanks for your help! I got it to work. I had been staring at it for so long that my mind wasn't clear. Took a break from it yesterday, came back to it today and was able to figure it out in less than 5 minutes! You guys are awesome, I love stackoverflow!
function checklogin($email, $pass) {
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(udogoo, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$no_rows = mysql_num_rows($result);
if ($no_rows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
$userid = $user_data['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = '$userid'");
$isadmin2 = mysql_fetch_array($isadmin);
$isadmin3 = $isadmin2['userlevel'];
if ($isadmin3 == "9"){
$_SESSION['admin'] = true;
return true;
}
}
else
{
return FALSE;
}
}
You have a return true; if the user data exists. In fact, you only check or admin-ness if the user doesn't exist.
Remove that return true;, as it's not needed there. If you want, add else return false; after the check for the user's existence, and return true; right at the end.
Your logic is flawed as well, here:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$email = mysql_real_escape_string($email);
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = '$email'
AND `password` = '$pass'
LIMIT 1"; //I certainly hope you check email for injection before passing it here. Also want the LIMIT 1 on there because you are only expecting a single return, and you should only get one since `email` should be unique since you're using it as a credential, and this will stop it from looking through all the rows for another match once it finds the one that matches.
$result = mysql_query($sql);
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
if($user_data['userlevel'] == 9)
{
$_SESSION['admin'] = true;
}
else
{
$_SESSION['admin'] = false;
}
return true;
}
return false;
}
This should work. No good reason to do two queries when one will do just fine. Returns true if user is logged in, false if user doesn't exist or credentials don't match.
Oops, small syntax error in the SQL statement, corrected. Bigger syntax error also corrected.
And here's how you do the top part in PDO:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$dbname = 'test';
$dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;
$conn = new PDO($dsn,$user,$password); //Establish connection
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = :email
AND `password` = :pass
LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':email',$email,PDO::PARAM_STR,128) //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
$stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32) //MD5s should always have a length of 32
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute(); //almost equivalent to mysql_query
$user_data = $stmt->fetch(); //Grab the data
if(is_array($user_data) && count($user_data) == 2) //Check that returned info is an array and that we have both `userid` and `userlevel`
{
//Continue onwards
$userid = $user_data['user_id'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");
$user_data = mysql_fetch_array($result);
$userlevel = $user_data['userlevel'];
if($userlevel == '9')
{
$_SESSION['admin'] = true;
}
so, your complete code look like this::
<?php
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
//MY ANSWER START HERE
$userid = $_SESSION['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");
$user_data = mysql_fetch_array($result);
$userlevel = $user_data['userlevel'];
if($userlevel == '9')
{
$_SESSION['admin'] = true;
}
//END HERE
}
else
{
return false;
}
}
?>