所以我正在尝试为我的网站编写这个脚本。 它看起来很混乱和破碎。 也许有人可以帮我整理一下并解释可能不正确的内容。 还有,有办法缩短它,看起来有点不安全。 谢谢。
<?php
class Register
{
private $username;
private $password;
private $password2;
private $passmd5;
private $email;
private $email2;
private $errors;
private $rtoken;
public function __construct()
{
$this->errors = array();
$this->username = $this->filter($_POST['ruser']);
$this->password = $this->filter($_POST['rpass']);
$this->password2 = $this->filter($_POST['rpass2']);
$this->email = $this->filter($_POST['remail']);
$this->email2 = $this->filter($_POST['remail2']);
$this->rtoken = $_POST['rtoken'];
$this->passmd5 = md5($this->password);
}
public function process()
{
if ($this->valid_rtoken() && $this->valid_data())
$this->register();
return count($this->errors) ? 0 : 1;
}
public function filter($var)
{
return preg_replace('/[^a-zA-Z0-9@.]/', '', $var);
}
public function register()
{
mysql_query("INSERT INTO users(username,password,email) VALUES ('{$this->username}','{$this->passmd5}','{$this->email}')");
if (mysql_affected_rows() < 1)
$this->errors[] = '<font color="red">Database error</font>';
}
public function user_exists()
{
$data = mysql_query("SELECT ID FROM users WHERE username = '{$this->username}'");
return mysql_num_rows($data) ? 1 : 0;
}
public function email_exists()
{
$data = mysql_query("SELECT ID FROM users WHERE email = '{$this->email}'");
return mysql_num_rows($data) ? 1 : 0;
}
public function show_errors()
{
echo "";
foreach ($this->errors as $key => $value)
echo $value . "<br>";
}
public function valid_data()
{
if ($this->user_exists())
$this->errors[] = '<font color="red">Username Exists</font>';
if ($this->email_exists())
$this->errors[] = '<font color="red">email exists</font>';
if (empty($this->username))
$this->errors[] = '<font color="red">check your username</font>';
if (empty($this->password))
$this->errors[] = '<font color="red">check your password</font>';
if ($this->password != $this->password2)
$this->errors[] = '<font color="red">Passwords do not match</font>';
if (empty($this->email) || !eregi('^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,4}$', $this->email))
$this->errors[] = '<font color="red">Check your email</font>';
if ($this->email != $this->email2)
$this->errors[] = '<font color="red">Emails do not match</font>';
return count($this->errors) ? 0 : 1;
}
public function valid_rtoken()
{
if (!isset($_SESSION['rtoken']) || $this->rtoken != $_SESSION['rtoken'])
$this->errors[] = '<font color="red">Check</font>';
return count($this->errors) ? 0 : 1;
}
}
?>
答案 0 :(得分:3)
Swoosh,总有更好的方法来编写代码。我希望挑战你重新思考为什么你的代码很长,为什么它可能不安全,而不是为你重写你的代码。希望你能以这种方式学到更多东西。
首先,使用MD5散列密码是完全不安全的。请忘记MD5曾经存在过,请不要使用SHA1来保证安全。相反,你应该使用bcrypt或PBKDF2(使用SHA2或Whirlpool和~2000 +轮次)。我建议您参考我对Secure Hash and Salt for PHP Passwords的回答,获取有关文章和库的提示和链接,以帮助实现更好的安全性。
其次,自PHP 5.5起,mysql_ *函数为deprecated。使用MySQLi可以帮助您,但您应该使用一致的界面(如PDO)来处理连接,并查询转义/过滤。虽然您可能没有在PHP 5.5中构建软件,但是如果主机决定升级您的PHP版本,您将无法控制。尽可能地优化未来的兼容性。此外,PDO还有一些很好的功能,在its documentation中有解释。
第三,不应使用正则表达式来“过滤”查询变量。您可以做的最安全的事情是对任何数字使用intval / floatval,并通过您使用的数据库库转义其余数据,例如mysql_escape_string(或mysqli_real_escape_string)或使用prepared statements(这将是为你清理变量。)
第四,您将显示逻辑放入对象中。想一想:这个对象实现的目的/角色是什么?它是否处理注册逻辑?它是否存储注册数据?在这里使用Single Responsibility Principle是个好主意。看起来该对象应该像混合模型控制器一样,其中包含表示信息。您可以将其扩展为RegistrationModel和RegistrationController类,以处理临时存储数据,甚至决定执行其他操作。但请记住,你的班级承担的责任越多,它就越有必要打破。
此外,通过将Register的所有属性设为私有,您不能有多种注册方式。如果您想要简化流程,例如通过OAuth(例如Twitter或Facebook)登录,但需要重用Register中的某些逻辑,该怎么办?这些属性至少应该受到保护,以便您可以继承这些属性,甚至是公共属性,以便另一个对象可以与它们交互(例如,通知用户注册成功的对象)。