找不到 PHP 查询和答案中的 SQLSTATE[HY093]
SQLSTATE[HY093] in PHP Query and Answer cannot be found
我已经在一个网站上工作了一段时间,您可以使用 api 和 Windows 应用程序进行编辑,我已经完成了所有代码,所以我添加了一个带有工作令牌的注册系统(哈希值)。
我去创建了它们,所以我创建了登录系统注册和登录,它起作用了,所以我决定将令牌系统添加到代码中,我测试了它可以工作的令牌系统,但正常未受影响然后代码开始失败(这和我添加令牌系统之前一样),我搜索了代码但找不到问题,这是我一直在使用的整个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],我让它输出了所有我能帮助我理解的东西,但没有任何东西会告诉我参数这是导致错误的原因,输出是
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();
我已经在一个网站上工作了一段时间,您可以使用 api 和 Windows 应用程序进行编辑,我已经完成了所有代码,所以我添加了一个带有工作令牌的注册系统(哈希值)。
我去创建了它们,所以我创建了登录系统注册和登录,它起作用了,所以我决定将令牌系统添加到代码中,我测试了它可以工作的令牌系统,但正常未受影响然后代码开始失败(这和我添加令牌系统之前一样),我搜索了代码但找不到问题,这是我一直在使用的整个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],我让它输出了所有我能帮助我理解的东西,但没有任何东西会告诉我参数这是导致错误的原因,输出是
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();