在PHP查询和应答中找不到SQLSTATE[HY093]


SQLSTATE[HY093] in PHP Query and Answer cannot be found

我已经在一个网站上工作了一段时间,你可以使用api和Windows应用程序进行编辑,我已经完成了所有的代码,所以我添加了一个带有工作令牌(hash)的注册系统。

我去创建了它们,所以我创建了登录系统注册和登录,它起了作用,所以我决定将令牌系统添加到代码中,我测试了令牌系统,它起作用,但正常的未受影响的代码随后开始失败(与我添加令牌系统之前相同),我搜索了代码,但找不到问题,以下是我一直在使用的整个PHP脚本:

<?php
require("common.php");
require("code.php");
//die("Registration is currently disabled");
if (!empty($_GET['token'])) {
$token = $_GET['token'];
if (getRegistrationValid($token)) {
    $username = getRegistrationUsername($token);
    $level    = getRegistrationLevel($token);
    // This if statement checks to determine whether the registration form has been submitted 
    // If it has, then the registration code is run, otherwise the form is     displayed 
    if (!empty($_POST)) {
        $username = getRegistrationUsername($token);
        $level    = getRegistrationLevel($token);
        // Ensure that the user has entered a non-empty username 
        if (empty($username)) {
            die("Problem with token. ERR[1]");
        }
        // Ensure that the user has entered a non-empty password 
        if (empty($_POST['password'])) {
            die("Please enter a password. ERR[2]");
        }
        // Make sure the user entered a valid E-Mail address 
        if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
            die("Invalid E-Mail Address. ERR[3]");
        }
        $query = " 
               SELECT 
                   1 
               FROM $dbtable 
               WHERE 
                   username = :username 
           ";
        $query_params = array(
            ':username' => $username
        );
        try {
            // These two statements run the query against your database table. 
            $stmt   = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            die("Failed to run query: " . $ex->getMessage() . " ERR[4]");
        }
        $row = $stmt->fetch();
        if ($row) {
            die("This username is already in use ERR[5]");
        }
        $email = $_POST['email'];
        $query = " 
               SELECT 
                   1 
               FROM $dbtable 
               WHERE 
                   email = :email 
           ";
        $query_params = array(
            ':email' => $email
        );
        try {
            $stmt   = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            die("Failed to run query: " . $ex->getMessage() . " ERR[6]");
        }
        $row = $stmt->fetch();
        if ($row) {
            die("This email address is already registered ERR[7]");
        }
        $query = " 
               INSERT INTO $dbtable ( 
                   username, 
                   password, 
                   salt, 
                   email,
                   level
               ) VALUES ( 
                   :username, 
                   :password, 
                   :salt, 
                   :email,
                   :level
               )
           ";
        $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
        $password = hash('sha256', $_POST['password'] . $salt);
        for ($round = 0; $round < 65536; $round++) {
            $password = hash('sha256', $password . $salt);
        }
        if($username == null) { die ("$ level == null"); }
        if($password == null) { die ("$ password == null"); }
        if ($salt == null) { die ("$ salt == null"); }
        if ($email == null) { die ("$ email == null"); }
        if ($level == null) { die ("$ level == null"); }
        $query_params = array(
            ':username' => $username,
            ':password' => $password,
            ':salt' => $salt,
            ':email' => $email,
            ':level:' => $level
        );
        try {
            // Execute the query to create the user 
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $stmt   = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            // Note: On a production website, you should not output $ex->getMessage(). 
            // It may provide an attacker with helpful information about your code.  
            die("Failed to run query: " . $ex->getMessage() . " ERR[8] <br>" . $ex->getTraceAsString() . "<br>" . $ex->getLine() . "<br>" . $ex->getCode());
        }
        // This redirects the user back to the login page after they register 
        header("Location: login.php");
        die("Redirecting to login.php");
    }
} else {
    die("Invalid Token ERR[9]");
}
} else {
die("Invalid Token - No token found in post ERR[10]");
}
function getLevel($tok) {
$levelid = getRegistrationLevel($tok); 
if($levelid == 0) {
    return "Standard user";
} 
if ($levelid == 1) {
    return "Admin";
} 
if ($levelid == 2) {
    return "Webpage Editor";
}
return "Unknown";
}
?>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-    min.css">
<body style="background-color: rgb(219, 219, 219);">
  <div style="text-align: center;">
  <div style="text-align: center;"></div>
<div
 style="border: 10px solid rgb(201, 214, 228); margin: 30px auto 0px; padding: 10px; width: 154px; background-color: rgb(237, 237, 237); font-size: 12px; font-family: Tahoma; color: rgb(129, 129, 129); text-align: left;">
<div style="text-align: center;"></div>
<div
 style="font-size: 30px; font-family: impact; width: 100%; margin-bottom: 5px; text-align: center;"><span
 style="font-weight: bold;">Register</span>
 <br>
<strong style="font-family: Gisha;"></strong>
</div>
<br>
  <form action="register.php?token=<?php echo $token; ?>" method="post"> 
  Username: <?php echo $username; ?><br>
    <br>
  Level: <?php echo getLevel($token); ?><br>
    <br>
  E-Mail:<br>
    <input name="email" value="" type="text" style="width:100%"> <br>
    <br>
  Password:<br>
    <input name="password" value="" type="password" style="width:100%">
    <br>
    <br>
    <input value="Register" type="submit" class="pure-button pure-button-primary" style="width:100%"> 
    <br>
    <br>
  </form>
</div>

在我将脚本上传到web服务器并尝试运行它之后,我出现了错误[10],我让它输出我所能帮助我理解的所有内容,并且没有任何失速会向我显示导致错误的parm,输出是

Failed to run query: SQLSTATE[HY093]: Invalid parameter number: parameter         was not defined ERR[8] 
#0 /home/webcontroller/public_html/admin/manage/register.php(180): PDOStatement->execute(Array) #1 {main}
180
HY093

以下是那些无法理解或想知道的人应该发生的事情,

[Pseudo Code]
  1. User gets mailed or sent link to ..../admin/register.php?token=blah (or slam head here - qwesdnloweadkfnjln)
  2. The form will load showing the designated username
  3. The user will enter in the details required
  4. User clicks submit then redirect with post request
  5. Check the email, if email is used - inform user and die to stop registration
  6. Encrypt the password
  7. Create SQL Query (To insert information into DB)
  8. Create SQL Query Params (anti SQL Injection)
  9. Run Query -> insert information
  10. Redirect to login page for user to continue their advert to whatever awaits them.

您的一个参数数组键中有一个额外的冒号:

$query_params = array(
        ':username' => $username,
        ':password' => $password,
        ':salt' => $salt,
        ':email' => $email,
        ':level:' => $level  // this should just be ':level'
    );

附带说明一下,如果您单独绑定参数,而不是作为一个完整的数组传递,那么您应该得到一个更具辨别力的错误消息:

$query = "....";
$stmt = $db->prepare($query);
$stmt->bindParam(":username", $username);
...
$result = $stmt->execute();