我很难找出导致问题的原因。首先,我使用panique php-login-advanced。问题是,只要用户注册成功,他们就不会插入数据库。我目前正在使用wamp / w phpmyadmin。我事先禁用了整个邮件系统,看看用户是否被添加到了数据库中,但他们并没有。我假设我可能搞砸了查询。但如果我这样做,我会收到错误。
我没有错误。注册成功时
class Registration
{
/**
* @var object $db_connection The database connection
*/
private $db_connection = null;
/**
* @var bool success state of registration
*/
public $registration_successful = false;
/**
* @var bool success state of verification
*/
public $verification_successful = false;
/**
* @var array collection of error messages
*/
public $errors = array();
/**
* @var array collection of success / neutral messages
*/
public $messages = array();
/**
* the function "__construct()" automatically starts whenever an object of this class is created,
* you know, when you do "$login = new Login();"
*/
public function __construct()
{
session_start();
// if we have such a POST request, call the registerNewUser() method
if (isset($_POST["register"])) {
$this->registerNewUser($_POST['user_name'], $_POST['user_email'], $_POST['user_password_new'], $_POST['user_password_repeat'], $_POST['user_safecode'],$_POST["captcha"]);
// if we have such a GET request, call the verifyNewUser() method
} else if (isset($_GET["id"]) && isset($_GET["verification_code"])) {
$this->verifyNewUser($_GET["id"], $_GET["verification_code"]);
}
}
/**
* Checks if database connection is opened and open it if not
*/
private function databaseConnection()
{
// connection already opened
if ($this->db_connection != null) {
return true;
} else {
// create a database connection, using the constants from config/config.php
try {
// Generate a database connection, using the PDO connector
// @see http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
// Also important: We include the charset, as leaving it out seems to be a security issue:
// @see http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers#Connecting_to_MySQL says:
// "Adding the charset to the DSN is very important for security reasons,
// most examples you'll see around leave it out. MAKE SURE TO INCLUDE THE CHARSET!"
$this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME . ';charset=utf8', DB_USER, DB_PASS);
return true;
// If an error is catched, database connection failed
} catch (PDOException $e) {
$this->errors[] = MESSAGE_DATABASE_ERROR;
return false;
}
}
}
/**
* handles the entire registration process. checks all error possibilities, and creates a new user in the database if
* everything is fine
*/
private function registerNewUser($user_name, $user_email, $user_password, $user_password_repeat, $user_safecode, $captcha)
{
// we just remove extra space on username and email
$user_name = trim($user_name);
$user_email = trim($user_email);
// check provided data validity
// TODO: check for "return true" case early, so put this first
if (strtolower($captcha) != strtolower($_SESSION['captcha'])) {
$this->errors[] = MESSAGE_CAPTCHA_WRONG;
} elseif (empty($user_name)) {
$this->errors[] = MESSAGE_USERNAME_EMPTY;
} elseif (empty($user_password) || empty($user_password_repeat)) {
$this->errors[] = MESSAGE_PASSWORD_EMPTY;
} elseif ($user_password !== $user_password_repeat) {
$this->errors[] = MESSAGE_PASSWORD_BAD_CONFIRM;
} elseif (strlen($user_password) < 6) {
$this->errors[] = MESSAGE_PASSWORD_TOO_SHORT;
} elseif (strlen($user_name) > 64 || strlen($user_name) < 2) {
$this->errors[] = MESSAGE_USERNAME_BAD_LENGTH;
} elseif (!preg_match('/^[a-z\d]{2,64}$/i', $user_name)) {
$this->errors[] = MESSAGE_USERNAME_INVALID;
} elseif (empty($user_email)) {
$this->errors[] = MESSAGE_EMAIL_EMPTY;
} elseif (strlen($user_email) > 64) {
$this->errors[] = MESSAGE_EMAIL_TOO_LONG;
} elseif (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
$this->errors[] = MESSAGE_EMAIL_INVALID;
} elseif (empty($user_safecode)) {
$this->errors[] = MESSAGE_SAFECODE_EMPTY;
} elseif (strlen($user_safecode) < 12) {
$this->errors[] = MESSAGE_SAFECODE_BAD_LENGTH;
} elseif (strlen($user_safecode) > 64) {
$this->errors[] = MESSAGE_SAFECODE_BAD_LENGTH;
// finally if all the above checks are ok
} else if ($this->databaseConnection()) {
// check if username or email already exists
$query_check_user_name = $this->db_connection->prepare('SELECT user_name, user_email FROM users WHERE user_name=:user_name OR user_email=:user_email');
$query_check_user_name->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_check_user_name->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_check_user_name->execute();
$result = $query_check_user_name->fetchAll();
// if username or/and email find in the database
// TODO: this is really awful!
if (count($result) > 0) {
for ($i = 0; $i < count($result); $i++) {
$this->errors[] = ($result[$i]['user_name'] == $user_name) ? MESSAGE_USERNAME_EXISTS : MESSAGE_EMAIL_ALREADY_EXISTS;
}
} else {
// check if we have a constant HASH_COST_FACTOR defined (in config/hashing.php),
// if so: put the value into $hash_cost_factor, if not, make $hash_cost_factor = null
$hash_cost_factor = (defined('HASH_COST_FACTOR') ? HASH_COST_FACTOR : null);
// crypt the user's password with the PHP 5.5's password_hash() function, results in a 60 character hash string
// the PASSWORD_DEFAULT constant is defined by the PHP 5.5, or if you are using PHP 5.3/5.4, by the password hashing
// compatibility library. the third parameter looks a little bit shitty, but that's how those PHP 5.5 functions
// want the parameter: as an array with, currently only used with 'cost' => XX.
$user_password_hash = password_hash($user_password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor));
// generate random hash for email verification (40 char string)
$user_activation_hash = sha1(uniqid(mt_rand(), true));
// write new users data into database
$query_new_user_insert = $this->db_connection->prepare('INSERT INTO users (user_name, user_password_hash, user_email, user_activation_hash, user_registration_ip, user_registration_datetime, user_accountstatus, user_group, user_safecode, user_mainaccount) VALUES(:user_name, :user_password_hash, :user_email, :user_activation_hash, :user_registration_ip, now(), :user_accountstatus, :user_group, :user_safecode, :user_mainaccount)');
$query_new_user_insert->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_password_hash', $user_password_hash, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_activation_hash', $user_activation_hash, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_registration_ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_accountstatus', 1, PDO::PARAM_INT);
$query_new_user_insert->bindValue(':user_group', 1, PDO::PARAM_INT);
$query_new_user_insert->bindValue(':user_safecode', $user_safecode, PDO::PARAM_STR);
$query_new_user_insert->bindValue(':user_mainaccount', "NULL", PDO::PARAM_STR);
$query_new_user_insert->execute(); // Seems like this doesn't execute
// id of new user
$user_id = $this->db_connection->lastInsertId();
if ($query_new_user_insert) {
$send_mail = true; //bypass mailing system first
// send a verification email $this->sendVerificationEmail($user_id, $user_email, $user_activation_hash)
if ($send_mail) {
// when mail has been send successfully
$this->messages[] = MESSAGE_VERIFICATION_MAIL_SENT;
$this->registration_successful = true;
} else {
// delete this users account immediately, as we could not send a verification email
$query_delete_user = $this->db_connection->prepare('DELETE FROM users WHERE user_id=:user_id');
$query_delete_user->bindValue(':user_id', $user_id, PDO::PARAM_INT);
$query_delete_user->execute();
$this->errors[] = MESSAGE_VERIFICATION_MAIL_ERROR;
}
} else {
$this->errors[] = MESSAGE_REGISTRATION_FAILED;
}
}
}
}
/*
* sends an email to the provided email address
* @return boolean gives back true if mail has been sent, gives back false if no mail could been sent
*/
public function sendVerificationEmail($user_id, $user_email, $user_activation_hash)
{
$mail = new PHPMailer;
// please look into the config/config.php for much more info on how to use this!
// use SMTP or use mail()
if (EMAIL_USE_SMTP) {
// Set mailer to use SMTP
$mail->IsSMTP();
//useful for debugging, shows full SMTP errors
//$mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
// Enable SMTP authentication
$mail->SMTPAuth = EMAIL_SMTP_AUTH;
// Enable encryption, usually SSL/TLS
if (defined(EMAIL_SMTP_ENCRYPTION)) {
$mail->SMTPSecure = EMAIL_SMTP_ENCRYPTION;
}
// Specify host server
$mail->Host = EMAIL_SMTP_HOST;
$mail->Username = EMAIL_SMTP_USERNAME;
$mail->Password = EMAIL_SMTP_PASSWORD;
$mail->Port = EMAIL_SMTP_PORT;
} else {
$mail->IsMail();
}
$mail->From = EMAIL_VERIFICATION_FROM;
$mail->FromName = EMAIL_VERIFICATION_FROM_NAME;
$mail->AddAddress($user_email);
$mail->Subject = EMAIL_VERIFICATION_SUBJECT;
$link = EMAIL_VERIFICATION_URL.'?id='.urlencode($user_id).'&verification_code='.urlencode($user_activation_hash);
// the link to your register.php, please set this value in config/email_verification.php
$mail->Body = EMAIL_VERIFICATION_CONTENT.' '.$link;
if(!$mail->Send()) {
$this->errors[] = MESSAGE_VERIFICATION_MAIL_NOT_SENT . $mail->ErrorInfo;
return false;
} else {
return true;
}
}
/**
* checks the id/verification code combination and set the user's activation status to true (=1) in the database
*/
public function verifyNewUser($user_id, $user_activation_hash)
{
// if database connection opened
if ($this->databaseConnection()) {
// try to update user with specified information
$query_update_user = $this->db_connection->prepare('UPDATE users SET user_active = 1, user_activation_hash = NULL WHERE user_id = :user_id AND user_activation_hash = :user_activation_hash');
$query_update_user->bindValue(':user_id', intval(trim($user_id)), PDO::PARAM_INT);
$query_update_user->bindValue(':user_activation_hash', $user_activation_hash, PDO::PARAM_STR);
$query_update_user->execute();
if ($query_update_user->rowCount() > 0) {
$this->verification_successful = true;
$this->messages[] = MESSAGE_REGISTRATION_ACTIVATION_SUCCESSFUL;
} else {
$this->errors[] = MESSAGE_REGISTRATION_ACTIVATION_NOT_SUCCESSFUL;
}
}
}
}
答案 0 :(得分:0)
嗨,你正在使用巨大的Bindvalue,但执行正在运行,但你可以通过简单的ex来优化它:
$stmt->execute(array(
':user_name' => $user_name,
':user_password_hash' => $user_password_hash
));
//add the user ID primary field you are missing that Ajmal PraveeN :)
$user_id = $this->db_connection->lastInsertId('uniqueidfield');
以及为什么缺少唯一ID字段..
答案 1 :(得分:0)
设置PDO::ERRMODE_EXCEPTION
以查看错误。默认行为仅设置可以“手动”检查的属性(PDO::ERRMODE_SILENT
)。
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
$this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME . ';charset=utf8', DB_USER, DB_PASS, $options);