I have recently switched over to using PDO from mySQLi for all mySQL queries and for the most part, it has been pretty straight forward. I recently completed a web app and am now implementing a PDO based sign up/sign in workflow for the first time.
After extensive research, I wrote the PHP and PDO for sign up and login. On Submit of sign up, the page refreshes, nothing appears in DB and the page does not redirect accordingly.
Below is the code to connect to the DB, register a user, and redirect them to their profile page.
registerUser.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require 'dbconfig.php';
$url = "http://mattmcclintock.com";
$uname = null;
$umail = null;
$upass = null;
$unem = array($uname, $umail);
$umore = array($uname, $umail, $upass);
$errors = array();
$message = null;
if (isset($_POST['btn-signup'])) {
// good idea to trim non-password fields
$uname = trim($_POST['txt_uname']);
$umail = trim($_POST['txt_umail']);
$upass = $_POST['txt_upass'];
// I am assuming you want to check every field independently, so you need to
// group your IF conditions for each field
// empty string is a falsey (i.e. '' == false => true; though '' === false => false),
// so we'll shorten your IF conditions from $var == '' to !$var
if (!$uname) {
$errors['txt_uname'] = "provide username !";
}
if (!$umail) {
$errors['txt_umail'] = "provide email id !";
} elseif (!filter_var($umail, FILTER_VALIDATE_EMAIL)) {
$errors['txt_umail'] = 'Please enter a valid email address !';
}
if (!$upass) {
$errors['txt_upass'] = "provide password !";
} elseif (strlen($upass) < 6) {
$errors['txt_upass'] = "Password must be atleast 6 characters";
}
// Assuming you only want to check for duplications when there are no errors with the username or email
if (empty($errors['txt_umail']) && empty($errors['txt_umail'])) {
if ($row = $user->getUserByUsernameOrEmail($uname, $umail)) {
if ($row['user_name'] == $uname) {
$errors['txt_uname'] = "sorry username already taken !";
} else {
$errors['txt_umail'] = "sorry email id already taken !";
}
}
}
// empty array is also a falsey
if ($errors) {
$message = "There are errors";
// WHOA! where did $fname and $lname come from?!
// original: if($user->register($fname,$lname,$uname,$umail,$upass)) {
} elseif ($user->register($uname, $umail, $upass)) {
$user->redirect($url);
} else {
$message = "An unexpected error has occurred";
}
}
?>
And the corresponding HTML for to signup with.
<form id="signupform" method="POST" action="registerUser.php" class="form-horizontal" role="form">
<div id="signupalert" style="display:none" class="alert alert-danger">
<p>Error:</p>
<span></span>
</div>
<div class="form-group">
<label for="email" class="col-md-3 control-label">Username</label>
<div class="col-md-9">
<input type="text" class="form-control" name="txt_uname" placeholder="Enter Username" value="<?php if(isset($error)){echo $uname;}?>" />
</div>
</div>
<div class="form-group">
<label for="firstname" class="col-md-3 control-label">Email</label>
<div class="col-md-9">
<input type="text" class="form-control" name="txt_umail" placeholder="Enter E-Mail ID" value="<?php if(isset($error)){echo $umail;}?>" />
</div>
</div>
<div class="form-group">
<label for="password" class="col-md-3 control-label">Password</label>
<div class="col-md-9">
<input type="password" class="form-control" name="txt_upass" placeholder="Enter Password" />
</div>
</div>
<div class="form-group">
<!-- Button -->
<div class="col-md-offset-3 col-md-9">
<button type="submit" class="btn btn-block btn-primary" name="btn-signup">
<i class="glyphicon glyphicon-open-file"></i> SIGN UP
</button>
</div>
</form>
Any help would be greatly appreciated. Having written exclusively in SQL switching over to PDO has been relatively difficult and I'm trying to get a feel for all of the common DB interactions and how to handle them with PDO.
Below I added code for class.user.php
class.User.php
<?php
class USER {
private $db;
public function __construct($DB_con)
{
$this->db = $DB_con;
}
public function getUserByUsernameOrEmail($uname, $umail)
{
try {
$stmt = $this->db->prepare("
SELECT user_name, user_email FROM users WHERE user_name= ? OR user_email = ?
");
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
} catch(PDOException $e) {
echo $e->getMessage();
}
return null;
}
// WHOA! where did $fname and $lname come from?!
// original: public function register($fname, $lname, $uname, $umail, $upass)
public function register($uname, $umail, $upass)
{
try {
$stmt = $this->db->prepare("
INSERT INTO users (user_name, user_email, user_pass) VALUES(?, ?, ?)
");
// keep things short and simple
$stmt->execute($uname, $umail, $upass);
// better to return the number of affected rows when dealing with insert/update/delete queries
return $stmt->rowCount();
} catch(PDOException $e) {
echo $e->getMessage();
}
return false;
}
public function login($uname, $umail, $upass)
{
try {
$stmt = $this->db->prepare("SELECT * FROM users WHERE user_name = ? OR user_email= ?");
$stmt->execute();
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (password_verify($upass, $row['user_pass'])) {
$_SESSION['user_session'] = $row['user_id'];
return true;
}
}
} catch (PDOException $e) {
echo $e->getMessage();
}
return false;
}
public function is_loggedin()
{
return isset($_SESSION['user_session']); // shortened
}
// your code is expecting the URL to be passed into the method
// original: public function redirect()
public function redirect($url)
{
header("Location: $url");
// it's good practice to exit
exit;
}
public function logout()
{
session_destroy();
unset($_SESSION['user_session']);
return true;
}
}
?>
dbconfig.php
<?php
session_start();
$DB_host = "bbb";
$DB_user = "bbb";
$DB_pass = "bbb";
$DB_name = "bbb";
try
{
$DB_con = new PDO("mysql:host={$DB_host};dbname= {$DB_name}",$DB_user,$DB_pass);
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
include_once 'class.User.php';
$user = new USER($DB_con);