0

This pset is confusing and I'm completely lost. How can I fix this bug?

Notice: Undefined offset: 0 in /home/ubuntu/workspace/pset7/public/register.php on line 39

The code:

    // Check if the username already exists
    $result = CS50::query("SELECT * FROM users WHERE username = ?", $_POST["username"]);
    // If not, insert it into the database
    if ($result === false)
    {
        CS50::query("INSERT INTO users (username, hash, cash) VALUES(?, ?, 10000.0000)", $_POST["username"], password_hash($_POST["password"], PASSWORD_DEFAULT));
    }
    $rows = CS50::query("SELECT LAST_INSERT_ID() AS id");
    $id = $rows[0]["id"]; // line 39
    $_SESSION[$id];

EDIT: Thanks to @DinoCoderSaurus' help, I fixed the bug. But I'm still not clear on what happened on the following lines.

$result = CS50::query("SELECT * FROM users WHERE username = ?", $_POST["username"]);

What exactly are stored in $result?

if ($result == false)

What exactly are compared?

PS: the spec and video need updates.

enter image description here

I did as told in the video. But @DinoCoderSaurus points out $result === false is wrong. This is a tough pset. The outdated spec and errors in the videos make the pset even more confusing... Hope CS50 staff could fix them. Thanks a lot!

2

Look carefully at this line: $_SESSION[$id];. Remember it is $_SESSION["id"] that controls whether a user is logged in or not.

This if ($result === false) is also a problem. Since the select query always returns an array, $result is always an array, regardless of whether it has any "rows" or not. Therefore that test always evaluates to false. The "identity" comparison operator (===), evaluates to true when the two operands have the same value and the same type. (Here is one of the many articles Mr. Google finds on the subject).

You might find some additional hints in the login section of the specification.

My advice is to slow down, give yourself a chance to adjust to these new languages and syntaxes. It is indeed frustrating to have spent all this time getting good at C (you must have done, you got through all the psets so far! :), and then suddenly facing 4 new languages -- PHP, HTML, CSS, SQL. Ahhhh! Trust what you know, research and learn what you don't. Once you get used to the $, PHP is similar enough to C that you will get comfortable very quickly. Play with the staff's implementation to get a good feeling of how the software should ultimately work. Since we don't have our old friend gdb, use var_dump and echo liberally so you can see things the way the computer sees them. Use phpMyAdmin to look at the data. In this case, for instance, if you examine the user table, you would find that the user is not inserted. As with all things programming: patience, practice, perseverance!

ANSWERS TO EDITS:

  1. What exactly are stored in $result? An associative array with the results of the SELECT query. If now rows are returned, $result is an empty array.
  2. What exactly are compared? This "==" is a loose comparison. You might find the Booleans and Type comparison sections of the php doc helpful.

  3. The spec and video are correct. $result === false is not the correct syntax when $result is from a SELECT query. The spec/video are comparing the result of this INSERT query.

CS50::query("INSERT IGNORE INTO users (username, hash, cash) VALUES(?, ?, 10000.0000)", $_POST["username"], password_hash($_POST["password"], PASSWORD_DEFAULT));

4
  • Thank you, Dino! The error line is $id = $rows[0]["id"]. This pset is really challenging. I read the spec and watched the videos many times, and have read through a php tutorial. But I still find too many details in the code impossible to understand and don't know what to do next. Do you have any advice?
    – Kevin King
    Nov 15 '16 at 13:40
  • Sorry, I did bad troubleshooting! :( I am rewriting an answer now. Nov 15 '16 at 14:54
  • Thank you, Dino! I've fixed the bug. But I am still not clear on some details. I've edited the post. Hope you could give more help. Thanks!
    – Kevin King
    Nov 16 '16 at 3:03
  • Thank you, Dino! So in loose comparison, an empty array() is the same as false, and an not empty array(...) is evaluated true. Am I right?
    – Kevin King
    Nov 17 '16 at 2:10
0

I see @DinoCoderSaurus have already replied, here's some additional insight though, in case something wasn't clear.

The undefined offset error in PHP occures when the interpreter cannot find the requested key, which in your case is id, you can use the built-in array_key_exists to check if a key exists: array_key_exists('id', $rows[0]);. So to fix this you must set $rows[0]["id"] to the ID in question.

See this thread for more

Update

$result = CS50::query("SELECT * FROM users WHERE username = ?", $_POST["username"]) here $result is assigned to the results of an SQL query, if the query fails, CS50::query() returns false; otherwise it will return ALL USERS WHOSE USERNAME IS EQUAL TO THE USERNAME STORED IN $_POST, the username stored in $_POST will be the user who just logged in. To check the 'actual' contents you can use the dump() function.

The === operator compares equality between variables of the same type, and the == operator compares if two variables are equal regardless of data type for example '5' == 5 but '5' !== 5 however 5 === 5.

2
  • Thank you, Kleiven! I've add two more questions about the details. Hope you could help. Thanks!
    – Kevin King
    Nov 16 '16 at 3:05
  • See the 'update' section in my answer.
    – kluvin
    Nov 16 '16 at 8:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .