Undefined & id jumps two to three counts

I added this one statement that messed me up so bad. All I was trying to do was keep the mysql user table id number (auto inc) to use later on another page. The redirect stopped working and “undefined” started showing up instead. I also noticed my auto incr counter started to increase by 2 instead of one.

if (mysqli_query($conn, $sql)) {
    $last_id = mysqli_insert_id($conn);
    echo "<script>document.write(localStorage.setItem('UserID', '.$last_id.'))</script>";
} else {
    echo "Error: " . $sql . "<br>" . mysqli_error($conn);

This is the php file i am using.

$servername = "test.ipagemysql.com";
$username = "user";
$password = "password";
$dbname = "churchpal";

$F_Name= $_POST['first_name'];
$L_Name= $_POST['last_name'];
$Pass_Hash= $_POST['user_pass'];
$Phone= $_POST['phone'];
$Email= $_POST['email'];

error_reporting (E_ALL ^ E_NOTICE);

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {

    // echo "Connected successfully...";

// Stops the entering of a blank records into user table.

$sql = "INSERT INTO $user_table (first_name, last_name, PasswordHash, phone, email)
VALUES ('$F_Name', '$L_Name', '$Pass_Hash', '$Phone', '$Email')";

if (mysqli_query($conn, $sql)) {
    $last_id = mysqli_insert_id($conn);
	echo "<script>document.write(localStorage.setItem('UserID', '".$last_id."'))</script>";
        //  echo "New record created successfully. Last inserted ID is: " . $last_id;

} else {
    //  echo "Error: " . $sql . "<br>" . mysqli_error($conn);

header("Location: http://praypal.club/userthankyou.html"); exit;

The reason your redirect stopped working is because you cannot output anything to the browser before a header() redirect. If you had php’s error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, you would be getting an error message about headers already sent/output started at …

The <script>... you are outputting to the browser that’s causing the redirect to stop working, shouldn’t be used anyways. By passing the last insert id through the browser, you are creating a security hole, depending on what you are using the value for later. All external data can be altered and cannot be trusted. Someone could alter the id to become the id of an existing administrator to your site, add injected sql to it, or add html/javascript to it. If you have a need to use this value, either use it in the code on the current page or pass it in a session variable. Do NOT pass it through the browser.

The id incrementing by 2 or more is most likely because the browser is requesting the page multiple times (ajax/html form submission), or possibly due to something you are doing on the server, such as including/requiring the posted code twice. It would take having all the relevant code to pin down the problem.

Next, here’s what your form processing code should/should-not be doing -

  1. Detect if a post method form was submitted before access any of the form data.
  2. Trim then validate all the inputs before using them, storing validation errors in an array using the field name as the array index. This array is also an error flag. If it is empty, there are no errors and you can use the form data. If it is not empty there are errors. You can test/display the content of this array at the appropriate location in the html document.
  3. Don’t copy variables to other variables for no reason. This is just a waste of typing. Instead, keep the form data as an array and just operate on elements in the array.
  4. Don’t unconditionally output raw database errors onto a web page. Instead, use exceptions for database statement errors and in most cases let php catch and handle the exceptions, where php will use it’s error related settings to control what happens with the actual error information (database statement errors will ‘automatically’ get displayed/logged the same as php errors.)
  5. Don’t put external, unknown, dynamic values directly into sql query statements. Instead, use prepared queries. You would also want to switch to the much simpler PDO extension. The mysqli extension is overly complicated and inconsistent.
  6. Use php’s password_hash() and password_verify() for the password value.
  7. The only redirect you should have in your post method form processing code is a redirect to the exact same url of the current page, to cause a get request for that page. If you want to display a one-time success message, store it in a session variable, then test, display, and clear the session variable.
  8. In most cases, just let php close the database connection for you when your script ends. Also, where you have the close statement is after an exit, and it won’t get executed anyways.
  9. The $user_table variable doesn’t exist in the posted code, so you apparently have more code involved in this problem. This non-posted code could be where some of the issues are at.
Sponsor our Newsletter | Privacy Policy | Terms of Service