我正在尝试检查我的数据库中是否有已放入的密钥。如果密钥存在,那么我需要检查以确保username
字段未被填充。如果有,则需要抛出错误,以便它不会更新并覆盖已存储在数据库中的信息。
一切正常。更新功能等唯一不起作用的部分是在更新数据库之前检查密钥是否存在以及username
部分是否已填满(不确定如何做到这一点)。
谢谢,
Cameron Andrews
代码:
// If the Register form has been submitted
$err = array();
if(strlen($_POST['username'])<4 || strlen($_POST['username'])>32){
$err[]='Your username must be between 3 and 32 characters!';
}
if(preg_match('/[^a-z0-9 _]+/i',$_POST['username'])){
$err[]='Your username contains invalid characters!';
}
if(!checkEmail($_POST['email'])){
$err[]='Your email is not valid!';
}
$resultN = mysql_query("SELECT * FROM Users WHERE key='".$_POST['kgen']."'");
while($row = mysql_fetch_array($resultN))//for the results that are returned set the local variables
{
if($_POST['kgen'] == $row['key']){
if($_POST['username'] == $row['usr']){
$err[]='Username already in use';
}
}else if($_POST['kgen'] == ""){
$err[]='Invalid Key Code!';
}else{
$err[]='Error occured please try again';
}
}
if(!count($err)){
// If there are no errors
$_POST['email'] = mysql_real_escape_string($_POST['email']);
$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['pass'] = mysql_real_escape_string($_POST['pass']);
// Escape the input data
$theName = $_POST['name'];
$theUser = $_POST['username'];
$thePass = $_POST['pass'];
$theEmail = $_POST['email'];
$theType = "member";
$theRegIP = $_SERVER['REMOTE_ADDR'];
$theDate = "NOW()";
$theKey = $_POST['kgen'];
// If everything is OK register
mysql_query("UPDATE cad.Users SET name = '$theName', usr = '$theUser', pass = '$thePass', email = '$theEmail', type = '$theType', regIP = '$theRegIP', dt = '$theDate' WHERE Users.key = '$theKey'");
答案 0 :(得分:0)
首先,您应该看到this。第二,我看,你有奇怪的逻辑。尽量简化它。 :)至于我,我认为它应该是这样的:
<?php
if (strlen($_POST['username']) < 4 || strlen($_POST['username']) > 32) {
throw new RuntimeException('Your username must be between 3 and 32 characters!');
} elseif (preg_match('/[^a-z0-9 _]+/i', $_POST['username'])) {
throw new RuntimeException('Your username contains invalid characters!');
} elseif(!checkEmail($_POST['email'])) {
throw new RuntimeException('Your email is not valid!');
} elseif (empty($_POST['kgen'])) {
throw new RuntimeException('Invalid Key Code!');
}
$resultN = mysql_query("SELECT * FROM Users WHERE `key`='{$_POST['kgen']}' AND `usr`='{$_POST['username']}';");
$user = mysql_fetch_array($resultN);
if (!empty($user)) {
throw new RuntimeException('Username already in use');
}
// if all is fine - update
您可以使用例外来检查错误。好处 - 如果失败,您不会进行下一次检查。您还可以显示用户异常消息或原因(更好地使用自定义异常)。否定 - 您无法获取错误列表。
答案 1 :(得分:0)
以下是我将如何处理它:
我会使用mysqli
或PDO
代替已弃用的mysql
函数。
我会重写所有查询以使用预准备语句而不是将查询字符串连接在一起 - 您现在有很多SQL注入漏洞。
但是,由于我不打算为你重写整段代码,我的方法的其余部分将根据你当前的mysql / concatenated-query-string方法进行描述。
我会在name
字段上放置一个唯一索引,但在字段上允许NULL值。
我只是运行更新查询,而不是尝试运行不必要的选择加上更新。
UPDATE cad.Users
SET
name = '$theName',
usr = '$theUser',
pass = '$thePass',
email = '$theEmail',
type = '$theType',
regIP = '$theRegIP',
dt = NOW() /* don't pass 'NOW()' in single quotes as you are currently doing */
WHERE
Users.key = '$theKey'
AND User.name IS NULL;
如果您在此处收到错误,则应查看错误消息,以确定更新是否因唯一约束违规而失败(用户尝试输入已在与其他键关联的其他记录中使用的名称)或其他一些意外的原因。
假设没有错误,我会调用mysql_affected_rows()
(或mysqli
或PDO
中的相应等效内容)。如果返回值为1,则进行更新。如果返回值为0,则表示没有更新,因为您没有满足WHERE条件的任何行。
如果您获得0个受影响的行,则可以重新查询数据库,如果您确实要确定原因是否不匹配密钥或现有用户名。
SELECT name FROM Users WHERE key = '$theKey';
如果结果中没有行,那是因为密钥丢失,否则是因为名称不是NULL值。
网络是在快乐路径用例中,您只对数据库而不是两个进行单个查询,如果您想确定没有针对这些情况发生更新的原因,则只需要两个查询。您当前的方法总是需要2个查询。