PHP MySQLi登录脚本运行时始终提示失败求助
Let's walk through the issues in your current code that's causing consistent login failures, and fix them one by one:
1. Mismatched POST Parameter Check (The #1 Culprit)
You're checking if $_POST["username"] exists, but your form is sending a field named usernamemail (you even assign $usernamemail = $_POST["usernamemail"]; right above!). This means the outer if condition never passes, so you always hit the "Invalid login credentials" message from the else block.
Fix:
Change the check to look for the correct parameter name:
if (isset($_POST["usernamemail"]) && isset($_POST["password"])) {
2. Session Start Placement
session_start() needs to run before any HTML output (including the <!DOCTYPE> tag), otherwise you'll get a "headers already sent" error that prevents sessions from working properly. Your current code runs it inside the <body> tag, after already sending HTML content.
Fix:
Move the session initialization to the very top of your script:
<?php if (session_status() == PHP_SESSION_NONE) { session_start(); } ?> <!DOCTYPE html> <html> <head> <title>Logging you in... | Project Club</title> </head> <body> <?php // Rest of your PHP code here ?> </body> </html>
3. Missing Connection Error Handling
You never check if your database connection succeeded. If there's a typo in your credentials or server info, the script will silently fail without telling you why.
Fix:
Add a connection check right after creating the mysqli object:
$conn = new mysqli($servername, $serverusername, $serverpassword, $serverdbname); // Check for connection errors if ($conn->connect_error) { die("Database connection failed: " . $conn->connect_error); }
4. SQL Injection Vulnerability (Critical Security Fix)
Directly inserting user input into your SQL query is a huge security risk—attackers can use this to steal or modify your database data. Always use prepared statements for user-supplied values.
Fix:
Replace your raw SQL query with a prepared statement:
// Replace your existing $sql and mysqli_query lines with this $sql = "SELECT * FROM login WHERE username=? OR email=?;"; $stmt = $conn->prepare($sql); // Bind the $usernamemail variable to both placeholders (ss = two string values) $stmt->bind_param("ss", $usernamemail, $usernamemail); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc();
5. Handle Missing User Results
Right now, if the username/email doesn't exist in the database, your code skips the password check entirely and doesn't show an error message. You need to explicitly handle this case.
Fix:
Add an else clause to the $row check:
if ($row) { $hashpwdcheck = password_verify($password, $row["password"]); if ($hashpwdcheck) { $_SESSION["username"] = $row["username"]; echo "<p>You are successfully logged in.</p>"; } else { echo "<p>Invalid login credentials.</p>"; } } else { echo "<p>Invalid login credentials.</p>"; }
Full Fixed Code
Here's the complete, corrected script incorporating all these fixes:
<?php if (session_status() == PHP_SESSION_NONE) { session_start(); } ?> <!DOCTYPE html> <html> <head> <title>Logging you in... | Project Club</title> </head> <body> <?php $servername = "censored"; $serverusername = "censored"; $serverpassword = "censored"; $serverdbname = "censored"; if (isset($_POST["usernamemail"]) && isset($_POST["password"])) { $usernamemail = $_POST["usernamemail"]; $password = $_POST["password"]; $conn = new mysqli($servername, $serverusername, $serverpassword, $serverdbname); if ($conn->connect_error) { die("Database connection failed: " . $conn->connect_error); } $sql = "SELECT * FROM login WHERE username=? OR email=?;"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $usernamemail, $usernamemail); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); if ($row) { $hashpwdcheck = password_verify($password, $row["password"]); if ($hashpwdcheck) { $_SESSION["username"] = $row["username"]; echo "<p>You are successfully logged in.</p>"; } else { echo "<p>Invalid login credentials.</p>"; } } else { echo "<p>Invalid login credentials.</p>"; } $stmt->close(); $conn->close(); } else { echo "<p>Invalid login credentials.</p>"; } ?> </body> </html>
内容的提问来源于stack exchange,提问作者user9552143

