1

I'm just learning PHP and I thought it would be a good idea to learn some MySQL too.So I started working on the code and for some strange reason I keep getting duplicate users which is really really bad.

<?php
$link = mysqli_connect(here i put the data);
if(!$link)
{
    echo "Error: " . mysqli_connect_errno() . PHP_EOL;
    exit;
}
else
{
    if(isset($_POST['user']))
    { echo "User set! "; } 
    else { echo "User not set!"; exit; }
    if(isset($_POST['pass']) && !empty($_POST['pass']))
    { echo "Password set! "; } 
    else { echo "Password not set!"; exit; } 
    $num = mysqli_num_rows(mysqli_query("SELECT * FROM `users` WHERE ( username = "."'".$_POST['user']."' )"));
    if($num > 0)
    { echo "Cannot add duplicate user!"; }
    mysqli_close($link);
}
?>

For some strange reason I don't get the output I should get.I've tried some solutions found here on StackOverflow but they didn't work.

6
  • 2
    missing first parameter $link in mysqli_query Commented Jul 7, 2016 at 11:25
  • 2
    ^ Yea, and SQL Injection! Commented Jul 7, 2016 at 11:25
  • 1
    I hate when people say "I'm not that far along..." or "This site will not be public..." or "It's only for school, so security doesn't matter...". If teachers and professors are not talking about security from day one, they're doing it wrong. Challenge them. They're teaching sloppy and dangerous coding practices which students will have to unlearn later. I also hate it when folks say, "I'll add security later..." or "Security isn't important now...". If you don't have time to do it right the first time, when will you find the time to add it later? Commented Jul 7, 2016 at 12:18
  • 1
    @JayBlanchard Nice comment. Commented Jul 7, 2016 at 12:24
  • 1
    @JayBlanchard came back 8 years later to say that I agree with you now more than ever :) Commented Sep 11, 2024 at 22:16

5 Answers 5

2

The first parameter of connectionObject is not given in mysqli_query:

$num = mysqli_num_rows(mysqli_query($link, "SELECT * FROM `users` WHERE ( `username` = '".$_POST['user']."' )"));
//----------------------------------^^^^^^^

Also, your code is vulnerable to SQL Injection. A simple fix would be:

$_POST['user'] = mysqli_real_escape_string($link, $_POST['user']);
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks dude! That was it :D
Even escaping the string is not safe!
Don't be hyperbolic @PraveenKumar ¯\_(ツ)_/¯ You know what I mean!
@JayBlanchard Seriously dude, after seeing that answer, I became hopeless! :P
It's pretty scary! :P
|
1

This could be a problem of race condition.

Imagine that two users wants to create the same username at the same time. Two processes will execute your script. So both scripts select from database and find out that there is not an user with required username. Then, both insert the username.

Best solution is to create unique index on username column in the database.

ALTER TABLE users ADD unique index username_uix (username);

Then try insert the user and if it fails, you know the username exists ...

1 Comment

Yeah, I'll consider that :)
0

mysqli_query must receive two parameters in order to work. In this case, your mysqli_connect.

$num = mysqli_num_rows(mysqli_query($link, "SELECT * FROM `users` WHERE ( username = "."'".$_POST['user']."' )"));

Also, you can be affected by SQL Injection, in this code.

Never add user input directly in your queries without filtering them.

Do that to make your query more readable and safe:

$u_name=mysqli_real_escape_string($link, $_POST['user']);
$num = mysqli_num_rows(mysqli_query($link, "SELECT * FROM `users` WHERE ( username = '$u_name' )"));

6 Comments

Yeah I'm not used to adding mysqli_query as parameter instead of variable.
I'm so used to OOP MySqli that I forget that some of those needs parameters.
Ah... Gotcha, makes sense... :D
Well I answered first, but you fixed his problem faster XD
Yes, but the downvote can be removed on this answer.
|
0

To use mysqli_* extension, you must include your connection inside of the parameters of all queries.

$query = mysqli_query($link, ...); // notice using the "link" variable before calling the query 
$num = mysqli_num_rows($query); 

Alternatively, what you could do is create a query() function within your website, like so:

$link = mysqli_connect(...);

function query($sql){
    return mysqli_query($link, $sql);
}

and then call it like so:

query("SELECT * FROM...");

Comments

0

Here's how to write your code using prepared statements and error checking.

Also uses a SELECT COUNT(*)... to find the number of users instead of relying on mysqli_num_rows. That'll return less data from the database and just seems cleaner imo.

<?php
$link = mysqli_connect(here i put the data);

if(!$link) {
  echo "Error: " . mysqli_connect_errno() . PHP_EOL;
  exit;
}
else if(!isset($_POST['user'])) {
  echo "User not set!"; exit;
} 

echo "User set! ";

if(!isset($_POST['pass']) || empty($_POST['pass'])) {
  echo "Password not set!"; exit;
}

echo "Password set! ";

$query = "SELECT COUNT(username)
  FROM users
  WHERE username = ?";

if (!($stmt = $mysqli->prepare($query))) {
  echo "Prepare failed: (" . mysqli_errno($link) . ") " . mysqli_error($link);
  mysqli_close($link);
  exit;
}

$user = $_POST ['user'];
$pass = $_POST ['pass'];

if(!mysqli_stmt_bind_param($stmt, 's',  $user)) {
  echo "Execute failed: (" . mysqli_stmt_errno($stmt) . ") " . mysqli_stmt_error($stmt);
  mysqli_stmt_close($stmt);
  mysqli_close($link);
  exit;
}

if (!mysqli_execute($stmt)) {
    echo "Execute failed: (" . mysqli_stmt_errno($stmt) . ") " . mysqli_stmt_error($stmt);
  mysqli_stmt_close($stmt);
  mysqli_close($link);
  exit;
}

$result = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
  $num = $row[0];
  if($num > 0) {
    echo "Cannot add duplicate user!";
  }
}

mysqli_stmt_close($stmt);
mysqli_close($link);

please do suggest fixes to syntax, this was typed from a phone

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.