-5

When logging into my Unity project, I get error "Array index is out of range" at this line of my C# code

   if (www.text[0] == '0')

www.text pulls from this php script (www.text is returning null when debugging so it must be an error with my script).

<?php

$con = mysqli_connect('localhost', 'root', 'root', 'unityaccess');

//check that connection happened
if (mysqli_connect_errno())
{
    echo "1: Connection failed"; //error code #1 = connection failed
    exit();
}

$username = $_POST["name"];
$password = $_POST["password"];

//check if name exists
$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE 
username = ' " . $username . "';";

$namecheck = mysqli_query($con, $namecheckquery) or die("2: Name check query 
failed"); //error code #2 - name check query failed
if (mysqli_num_rows($namecheck) != 1)
{
echo "5: Either no user with name, or more than one";
exit();
}

//get login info from query
$existinginfo = mysqli_fetch_assoc($namecheck)
$salt= $existinginfo["salt"];
$hash = $existinginfo["hash"];

$loginhash = crypt($password, $salt);
if($hash != $loginhash)
{
echo "6: Incorrect password"; //error code #6 - password does not hash to 
match table
exit();
}

echo "0\t" . $existinginfo["score"];

?>

I'm following a tutorial and am new to php and sql.

https://www.youtube.com/watch?v=NVdjlXgbiMM

In the tutorial his code is exactly the same as mine. Looking at it myself I would assume that the echo "0\t" . $existinginfo["score"]; is the problem, and that putting a tab isn't separating it into an array. In his code he runs it and it's fine though, so I must be missing something else?

JohnZ12
  • 183
  • 3
  • 14
  • 2
    You need to add more Unity code that makes the request. Looking at the current code, it looks like `www.text` is a `string`. The `www.text` result from the request is null or empty so when you try to access the individual `char` with `www.text[0]` it will throw that error because the array that holds the `char` is has `0` index. *Before accessing the returned result, check if there is an error with `isHttpError` and `isNetworkError`. If there is no error, use `string.IsNullOrEmpty` to verify that the `www.text` is not `null` before using it.* – Programmer Oct 15 '18 at 19:59
  • 2
    Does you PHP code reach the last line without any error? Because, if you pasted it correctly, it is broken. – Salman A Oct 15 '18 at 20:00
  • 2
    This PHP code *should* give you a fatal error (invalid syntax) on this line: `number of names matching != 1`, unless it's a copy/paste error and it's actually part of the comment on the previous line – rickdenhaan Oct 15 '18 at 20:03
  • 3
    Decide where the problem is and then post a question relevant to the appropriate language. Does the PHP output the expected data? If so, it's irrelevant. If not, then this is nothing to do with C#. – miken32 Oct 15 '18 at 20:04
  • 2
    PHP could also be crashing on a missing `;` on the line `$existinginfo = mysqli_fetch_assoc($namecheck)`. So the real question is similar to what @Programmer said: is the request giving you a HTTP error? – rickdenhaan Oct 15 '18 at 20:05
  • 2
    @miken32 OP said that the error is happening at `if (www.text[0] == '0')` and that's a C# code. – Programmer Oct 15 '18 at 20:06
  • 2
    @Programmer but it sounds like that error could be caused the PHP code not producing expected (or any) output. – miken32 Oct 15 '18 at 20:07
  • 1
    @miken32 Or it could that the request from C# to the server is failing and that happens sometimes. It could be C# or php issue but this question is missing so much on the C# side and attempted debugging made by OP so it's hard to conclude what or where the issue is. – Programmer Oct 15 '18 at 20:12
  • 1
    Replace the statement with `if (!String.IsNullOrEmpty(www.text) && www.text[0] == '0')` – Olivier Jacot-Descombes Oct 15 '18 at 20:14
  • Thank you for the help everyone. I still haven't figured it out, but www.text is returning null so it is a problem on the php side and not C#. I'm editing my question to remove the C# tag. – JohnZ12 Oct 15 '18 at 20:21
  • It was the missing ; that rickdenhaan suggested. Thank you! – JohnZ12 Oct 15 '18 at 20:24
  • @rickdenhaan, you were right about the error where it checks for the number of lines in $namecheck. Could you tell me what the problem is with that line? Thank you again so much. – JohnZ12 Oct 15 '18 at 20:30
  • You mean the `number of lines matching != 1` line? It's not code at all, it appears to belong at the end of the previous line as part of that comment. – rickdenhaan Oct 15 '18 at 21:05
  • @rickdenhaan, I'm sorry I didn't clarify but that was just an error in pasting the code. In the actual code the comment isn't posted to the next line. I still get error 5 however despite the database only having one instance of the username. – JohnZ12 Oct 15 '18 at 21:08
  • 1
    There does not appear to be a problem with the code, so you need to debug why it's giving you that error. What is the result of `mysqli_num_rows($namecheck)`? Does it indicate 0 results or more than 1? Is the value of `$username` what you expect it to be? If you execute that query manually on your database, do you get the same number of results? – rickdenhaan Oct 15 '18 at 21:12
  • @rickdenhaan I checked and the result of mysqli_num_rows($namecheck) is 0. The value of $username is the expected result. I've tried several usernames after registering them, and despite showing in the database manually, mysqli_num_rows returns 0. – JohnZ12 Oct 15 '18 at 21:28
  • Looking closer, there is a space at the start of the username: `username = ' " . $username`. So if `$username` is `"bob"`, your query is looking for `" bob"`. Remove the space between the `'` and `"`. – rickdenhaan Oct 15 '18 at 22:29
  • @rickdenhaan I appreciate it, but in an answer posted recently someone suggested that already and I did update the code, and it still returns the same result. This is what that line looks like now. $namecheckquery = "SELECT username, salt, hash, score FROM players WHERE username = '" . $username . "';"; – JohnZ12 Oct 15 '18 at 22:37
  • Then... I'm stumped. Are you sure you're looking at the same database? – rickdenhaan Oct 16 '18 at 14:03

1 Answers1

2

You have a space after the ' in the query on this line:

$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE 
username = ' " . $username . "';";

So if the username entered is user1 it will look in the database for <space>user1 (where <space> means a space character). Remove that space.

$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE 
username = '" . $username . "';";

Actually, it would be even better if you learned to use prepared statements, then problems like this are nearly impossible, as well as making the code safe from SQL-injection. Read How can I prevent SQL injection in PHP?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you Barmar, but removing the space still produces the same error. This is my current code which still returns error 5. $namecheckquery = "SELECT username, salt, hash, score FROM players WHERE username = '" . $username . "';"; – JohnZ12 Oct 15 '18 at 21:51
  • I do plan to learn about preventing sql injection as soon as possible, I just need to get to the point where I'm comfortable with the basics first since this is only my second day of learning sql/php. – JohnZ12 Oct 15 '18 at 21:52
  • Add `echo $namecheckquery;` and then try executing the query by hand. – Barmar Oct 15 '18 at 21:54
  • echo $namecheckquery returns: SELECT username, salt, hash, score FROM players WHERE username = 'boardtobits'; – JohnZ12 Oct 15 '18 at 21:58
  • And when you execute that query by hand, does it work? – Barmar Oct 15 '18 at 21:59
  • When I execute $namecheckquery, I get the desired result. However when I execute mysqli_num_rows($namecheck), the result is 0. I could bypass the if statement entirely and return the data, but since this is my first time learning how to use sql I want to make sure I'm doing it correctly. I'm just trying to figure out what I'm doing wrong in the if (mysqli_num_rows($namecheck) !=1) code for mysqli_num_rows to be returning 0 instead of 1. – JohnZ12 Oct 15 '18 at 22:07
  • I don't see anything wrong. If `mysqli_num_rows($namecheck)` returns 0, then `mysqli_fetch_assoc($namecheck)` should always return `FALSE`, not a row. – Barmar Oct 15 '18 at 22:09
  • So what would be the correct way to create a conditional statement returning an error if $username does not already exist, or if there are multiple instances in the database? – JohnZ12 Oct 15 '18 at 22:20
  • It shouldn't be possible to create multiple instances, `username` should be a unique column. Your code looks like the correct way to do it, I can't explain why it's not working. The only thing I saw wrong was the spaces. – Barmar Oct 15 '18 at 23:55