需要我的PHP验证帮助
问题描述:
我正在尝试执行表单注册验证,但我不知道我是否正确地做。需要我的PHP验证帮助
首先,我在我的表单中为每个空白字段存储一条错误消息。 之后,如果我的字段不是空的,我想验证用户名字段(从无效字符),密码和电子邮件
问题是当我删除死亡();在我的用户名验证有条件的行中,它会向我显示错误消息和成功消息,并将无效的用户名插入到我的数据库中。
我敢肯定,问题是在我的if($ numrows == 0)条件,但我不明白为什么。
<?php
session_start();
$con=mysql_connect('localhost','root','') or die(mysql_error());
mysql_select_db('user_registration') or die("cannot select DB");
if(isset($_POST["submit"])){
$arrErrors = array();
unset($_SESSION['errors']);
if($_POST['user'] == ''){
$arrErrors['user_not_completed'] = "Username is not completed!";
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
}
if($_POST['pass'] == ''){
$arrErrors['pass_not_completed'] = "Password is not completed!";
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
}
if($_POST['email'] == ''){
$arrErrors['email_not_completed'] = "Email is not completed!";
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
}
if(!empty($_POST['user']) && !empty($_POST['pass']) && !empty($_POST['email'])) {
$user=$_POST['user'];
$pass=$_POST['pass'];
$email=$_POST['email'];
if(!preg_match("/^[a-zA-Z'-]+$/",$user)) {
$arrErrors['invalid_user'] = "Username is invalid!";
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
die();
}
$query=mysql_query("SELECT * FROM users WHERE username='".$user."'");
$numrows=mysql_num_rows($query);
if($numrows==0){
$sql="INSERT INTO users(username,password, email) VALUES('$user','$pass', '$email')";
$result=mysql_query($sql);
if($result){
$arrErrors['succes'] = 'Account successfuly created!';
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
}
} else {
$arrErrors['already_exists'] = 'That username already exists!';
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
}
}
}
?>
答
这里是我建议你这样做:
<?php
//FIRST I WOULD CHECK IF SESSION EXIST BEFORE STARTING IT:
if (session_status() == PHP_SESSION_NONE || session_id() == '') {
session_start();
}
//NEXT I'D USE PDO AS MY DATABASE ABSTRACTION LAYER: IT HAS A LOT OF ADVANTAGES, REALLY:
//DATABASE CONNECTION CONFIGURATION:
defined("HOST") or define("HOST", "localhost"); //REPLACE WITH YOUR DB-HOST
defined("DBASE") or define("DBASE", "user_registration"); //REPLACE WITH YOUR DB NAME
defined("USER") or define("USER", "root"); //REPLACE WITH YOUR DB-USER
defined("PASS") or define("PASS", ""); //REPLACE WITH YOUR DB-PASS
if(isset($_POST["submit"])){
//THEN CLEAN UP THE SUBMITTED DATA TO AVOID POSSIBLE ATTACKS...
$user = isset($_POST['user']) ? htmlspecialchars(trim($_POST['user'])) : null; //PROTECT AGAINST ATTACKS
$pass = isset($_POST['pass']) ? htmlspecialchars(trim($_POST['pass'])) : null; //PROTECT AGAINST ATTACKS
$email = isset($_POST['email']) ? htmlspecialchars(trim($_POST['email'])) : null; //PROTECT AGAINST ATTACKS
$passRX = '#(^[a-zA-z0-9\-\+_\}\{\(\)])([\w\.\-\\:\;\+\(\)\/\}\{\(\)\ ])*\w*$#';
$userRX = '#(^[a-zA-z])([\w\.\-\(\)\ ])*\w*$#';
$arrErrors = array();
unset($_SESSION['errors']);
//CHECK IF USERNAME CONFORMS TO THE CUSTOM USERNAME REG-EXP...
if(!preg_match($userRX, $user)){
$arrErrors['user_not_completed'] = "Username is either not completed or is invalid!";
//SAVE ERRORS TO SESSION
$_SESSION['errors'] = $arrErrors;
//REDIRECT BACK TO REGISTER PAGE
header("Location: register.php");
exit;
}
//CHECK IF PASSWORD CONFORMS TO THE CUSTOM PASSWORD REG-EXP...
if(!preg_match($passRX, $pass)){
$arrErrors['pass_not_completed'] = "Password is not completed!";
//SAVE ERRORS TO SESSION
$_SESSION['errors'] = $arrErrors;
//REDIRECT BACK TO REGISTER PAGE
header("Location: register.php");
exit;
}
//CHECK IF E-MAIL CONFORMS TO THE STANDARD E-MAIL FORMAT USING BUILT-FUNCTIONS...
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$arrErrors['email_not_completed'] = "Email is not completed!";
//SAVE ERRORS TO SESSION
$_SESSION['errors'] = $arrErrors;
//REDIRECT BACK TO REGISTER PAGE
header("Location: register.php");
exit;
}
//BECAUSE WE HAVE SANITIZED VERSIONS OF OUR $user, $pass & $email VARIABLES
//WE CAN JUST USE THEM DIRECTLY HERE:
if($user && $pass && $email) {
//HERE WE BEGIN THE PDO HIGH-LEVEL MAGIC... ;-)
try {
$dbh = new PDO('mysql:host='.HOST.';dbname='. DBASE,USER,PASS);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT * FROM users WHERE username = :user");
$stmt->execute(['user' => $user]);
$objUser = $stmt->fetch(PDO::FETCH_OBJ);
//THIS USER DOES NOT ALREADY EXIST SO WE GO AHEAD AND CREATE A CORRESPONDING RECORD IN THE DB TABLE
if(!$objUser){
$stmt = $dbh->prepare("INSERT INTO users (username, password, email) VALUES(:user, :pass, :email)");
$stmt->bindParam(':user', $user);
$stmt->bindParam(':pass', $pass);
$stmt->bindParam(':email', $email);
$insertStatus = $stmt->execute();
if($insertStatus){
$arrErrors['succes'] = 'Account successfuly created!';
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
exit;
}
}else {
$arrErrors['already_exists'] = 'That username already exists!';
$_SESSION['errors'] = $arrErrors;
header("Location: register.php");
exit;
}
//GARBAGE COLLECTION
$dbh = null;
}catch(PDOException $e){
//YOU HANDLE YOUR EXCEPTIONS HERE IN YOUR OWN UNIQUE MANNER...
echo $e->getMessage();
}
}
}
?>
希望这有助于有点...
[小博](http://bobby-tables.com/)说[你的脚本存在SQL注入攻击风险。](http://*.com/questions/60174/how-can-i-prevent-sql-injection-in-php)。即使[转义字符串](http://*.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string)是不安全的! –
请[停止使用'mysql_ *'函数](http://*.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php)。 [这些扩展](http://php.net/manual/en/migration70.removed-exts-sapis.php)已在PHP 7中删除。了解[编写](http://en.wikipedia.org/ wiki/Prepared_statement)语句[PDO](http://php.net/manual/en/pdo.prepared-statements.php)和[MySQLi](http://php.net/manual/en/mysqli.quickstart .prepared-statements.php)并考虑使用PDO,[这真的很简单](http://jayblanchard.net/demystifying_php_pdo.html)。 –
请使用PHP的[内建函数](http://jayblanchard.net/proper_password_hashing_with_PHP.html)来处理密码安全性。如果您使用的PHP版本低于5.5,则可以使用'password_hash()'[兼容包](https://github.com/ircmaxell/password_compat)。确保你[不要逃避密码](http://*.com/q/36628418/1011527)或在哈希之前使用其他任何清理机制。这样做会改变密码并导致不必要的附加编码。 –