错误不会显示自己

时间:2013-08-09 02:19:20

标签: php mysql

我正在尝试为我正在制作的系统编写注册系统。目前,我收到一条MySQL错误,这让我想要在每次看到它时撕掉我的脑袋。

 function UserRegister($user,$pass,$email,$first,$last)
 {
$sqlfirst = mysql_real_escape_string($first);
$sqllast = mysql_real_escape_string($last);
$sqluser = mysql_real_escape_string($user);
$hashpass = crypt($pass);
$sqlpass = mysql_real_escape_string($hashpass);
$sqlemail = mysql_real_escape_string($email);
$sql = "SELECT * 
 FROM   planerentalusers 
 WHERE  user = '$sqluser' ";
if($result = mysqli_query($GLOBALS['db'],$sql))
{   
    $rowcount=mysqli_num_rows($result);
    if($rowcount == 1)
    {
        echo "ERROR: There is already an account with that username! Click <a href='/PHPCalTest/login.php>here </a>to login if this is you. Otherwise, go back and try a different username.";
    }
    else
    {
        $sql2 = "INSERT INTO planerentalusers (first,last,user,pass,email) VALUES ('$sqlfirst','$sqllast','$sqluser','$sqlpass','$sqlemail')";
        $result2 = mysqli_query($GLOBALS['db'],$sql);
        if($result2 == true)
        {
            return true;
        }
        else return false;
    }
}
else return false;
mysqli_free_result($result);
}

上面是抛出错误的函数。 没有抛出的PHP堆栈跟踪,所以这里是我指出的:查询失败。但是怎么样,我不明白。也许有人可以指出我正确的方向。

1 个答案:

答案 0 :(得分:2)

这不是您问题的直接答案。它已在评论行之间解决。

现在,如果您愿意,可以简化和保护您的代码:

  1. 使用prepared statements。这是很自然的,因为您已经使用mysqli_*扩展名。传递给准备好的INSERT语句的参数将被正确转义。
  2. 利用INSERT IGNORE语法并使用affected_rows检查受影响的行。这样,您只需执行一次所需的操作即可。
  3. 要使INSERT IGNORE正常工作,您必须在UNIQUE列上设置username约束。

    ALTER TABLE planerentalusers ADD UNIQUE (username);
    

    现在,如果您发出INSERT IGNORE语句且用户名不存在,则会插入一行,affected_rows将返回1。如果用户名已存在,那么IGNORE子句将允许您的INSERT语句完成而不会出现错误,affected_rows将返回0

    据说,你的功能的改进版本可能看起来像

    function UserRegister($db, $username, $pass, $email, $first, $last) {
        $sql = "INSERT IGNORE INTO planerentalusers (first, last, username, pass, email) VALUES (?, ?, ?, ?, ?)";
        // prepare the statement
        $stmt = $db->prepare($sql);
        if (!$stmt) {
            die('Can\'t prepare: ' . $db->error); //TODO better error handling
        }
        // bind parameters
        $stmt->bind_param('sssss', $first, $last, $username, $pass, $email);
        if (!$stmt) {
            die('Can\'t bind parameters: ' . $db->error); //TODO better error handling
        }
        // execute
        $stmt->execute();
        if (!$stmt) {
            die('Query execution failed: ' . $db->error); //TODO better error handling
        }
        // get the number of affected rows
        $affected_rows = $stmt->affected_rows;
        // close the statement
        $stmt->close();
    
        return $affected_rows;
    }
    

    和调用代码

    $first    = $_POST['first'];   
    $last     = $_POST['last'];    
    $username = $_POST['username'];
    $pass     = crypt($_POST['pass']);
    $email    = $_POST['email'];
    
    //create a connection to the database
    $db = new mysqli('localhost', 'user', 'password', 'dbname');
    if ($db->connect_errno) {
        die('Connection failed: ' . $db->connect_error); //TODO better error handling
    }
    
    if (!UserRegister($db, $username, $pass, $email, $first, $last)) {
        echo "ERROR: There is already an account with that username! Click <a href='/PHPCalTest/login.php'>here </a>to login if this is you. Otherwise, go back and try a different username.";
    } else {
        echo "Account successfully created";
    }
    

    请注意

    1. 对开放数据库连接的引用显式传递给函数,而不是使用$_GLOBALS['db']
    2. 表示逻辑(回显错误消息和链接)被移出到调用代码
    3. 在整个功能中实施基本错误处理