PDO: How to make checks - php

I create this class but i'm newbie in PHP OOP & PDO and i don't know how and where i must to make check to username is valid , email is valid and e.t.c..
This is my code
Class Users {
private $db;
public function __construct(Database $datebase) {
if (!$database instanceOf Database) {
throw new Exeption();
}
$this->db = $datebase;
}
public function userRegistration($username, $password, $email) {
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$regdate = date('d.m.Y');
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `regdate`) VALUES (?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $regdate);
return ($query->execute()) ? true : false ;
}
}

If you want to check something, use Respect/Validation. For example:
$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
$usernameValidator->validate($_POST['username']); //true or false
$passwordValidator = v::alnum()->length(10, null);
$passwordValidator->validate($_POST['password']); //true or false
v::email()->validate($_POST['email']); //true or false

To check if the username or email exist in your database you can use SQL to search the email or username.
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
If the query returns a value than the email or username already exist in your database. From there you can show your own validation.

To check check if user or email exist you don't need another class, just add another method called userExist or emailExist and run a query and then check if you get a result.
public function emailExist($email){
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
try{
$query->execute();
//use the if statement and $query->rowCount() to check if there is a result
$rows = $query->rowCount();
if($rows === 1){
return true;
} else {
return false;
}
}catch (PDOException $e) {
die($e->getMessage());
}
}

Related

PHP: PDO if user exists check doesn't work

I'm new to PHP, I created User class/object which has a function that checks for user, it returns $stmt->rowCount() but when I check for it in code it just skip it, register the user..
Here is the code:
if(empty($name_err) && empty($email_err) && empty($username_err) && empty($password_err) && empty($confirm_password_err)) {
if($user->doesUserExist($email) === 0) {
$password = password_hash($password, PASSWORD_DEFAULT);
$user->register($username, $name, $email, $password);
} else {
$global_err = "Email is already taken";
}
}
Here is the function from User class:
public function doesUserExist($email) {
$query = "SELECT * FROM users WHERE email = :email";
$stmt = $this->connection->prepare($query);
$stmt->bindParam(':email', $email);
$stmt->execute();
$rowcount = $stmt->rowCount($stmt);
return $rowcount;
}
instead of === in your condition of if($user->doesUserExist($email) === 0) try to change to ==
and then try to change your method like this:
public function doesUserExist($email) {
$query = "SELECT * FROM users WHERE email = '" . $email . "';";
$stmt = $this->connection->prepare($query);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$rowcount = count($stmt->fetchAll());
return $rowcount;
}
You should Try
Call the function
$checkemail=$api->checkuseremail($email);
if($checkemail)
{
echo $mail_check;
}
and define your function like this
public function checkuseremail($email)
{
$db=getDB();
$stmt = $db->prepare("Select id from table_name where email=:email");
$stmt->bindParam("email", $email, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if($count)
{
return true;
}
else
{
return false;
}
}
It will return email are already exist or not

php registration do not push to db issue

I've got 2 classes - db.class.php and user.class.php. Within second one I have 2 methods associated with registration - register and registerValidation. db file is responsible for specifying db credentials and initializing connection. I do not really want to pollute my post so I will only give you db code as a link because I don't really think that the problem lays there.
The code of register method and validation method is:
<?php
require_once 'token.php';
class User
{
//db and table name
private $conn;
private $table_name = "users";
// constructor with $db as database connection
public function __construct($db)
{
$this->conn = $db;
}
public function registerValidation($nick,$email,$password)
{
if(
(strlen($nick) < 5 || strlen($nick) > 20) ||
(strlen($email) < 3 || strlen($email) > 100) ||
(strlen($password) < 6 || strlen($password) > 50)
)
{
//$error = 'nick or email or password is wrong length';
//echo json_encode($error);
return false;
}
else
{
// query to check if email already exists
$query = "
SELECT
*
FROM
" . $this->table_name . "
WHERE
id = ?
OR
email = ?
";
// prepare query statement
$stmt = $this->conn->prepare($query);
// bind params
$stmt->bindParam(1, $nick);
$stmt->bindParam(2, $email);
// execute query
$stmt->execute();
//count if there is same
$num = $stmt->rowCount();
if ($num > 0)
{
return false;
}
else
{
return true;
}
}
}
public function register($nick,$email,$password)
{
try
{
$password = password_hash($password, PASSWORD_DEFAULT);
$query = "
INSERT INTO
users(user, user, user)
VALUES
(?, ?, ?)";
// prepare query statement
$stmt = $this->conn->prepare($query);
//bind values from user
$stmt->bindparam(1, $nick);
$stmt->bindparam(2, $email);
$stmt->bindparam(3, $password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
I also have file doRegister.php which is some kind of endpoint for client side:
<?php
if(isset($_POST['submit']))
{
if(!empty($_POST['nick'])
&& !empty($_POST['email'])
&& !empty($_POST['password']))
{
// instantiate database
require_once '../config/database.php';
$database = new Database();
$db = $database->getConnection();
require_once '../classes/user.php';
$user = new User($db);
if($user->registerValidation($_POST['nick'], $_POST['email'], $_POST['password']))
{
$user->register($_POST['nick'], $_POST['email'], $_POST['password']);
http_response_code(201);
}
else
{
http_response_code(400);
}
}
else
{
http_response_code(400);
}
}
else
{
http_response_code(400);
}
When I send http POST request via postman I get 201(created) but when I go to localhost/phpmyadmin after that, there is no new record inside user table in my mysql db. Why?
The register function is definitely returning false on execution of the insert statement. Also it looks like the columns are wrong.
$query = "
INSERT INTO
users(nick, email , password)
VALUES
(?, ?, ?)";
#before returning true or false do a check on execute()
return $stmt->execute() === true ? true : false;
Also before returning the header 201, do a check on the register function to verify that it was true and not false..

Something breaks while including a php class in ajax

I am having a problem while including a php class with ajax.
Basically I have index.php which loads with ajax example.php. example.php includes init.php, which in turn includes a bunch of classes. I narrowed it down to users.php class, which I pasted below. I also put init.php under it just in case.
The file simply will not load with ajax. It works fine if i go directly to it.
<?php
class Users{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function update_user($first_name, $last_name, $gender, $bio, $image_location, $id){
$query = $this->db->prepare("UPDATE `users` SET
`first_name` = ?,
`last_name` = ?,
`gender` = ?,
`bio` = ?,
`image_location`= ?
WHERE `id` = ?
");
$query->bindValue(1, $first_name);
$query->bindValue(2, $last_name);
$query->bindValue(3, $gender);
$query->bindValue(4, $bio);
$query->bindValue(5, $image_location);
$query->bindValue(6, $id);
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
}
public function change_password($user_id, $password) {
global $bcrypt;
/* Two create a Hash you do */
$password_hash = $bcrypt->genHash($password);
$query = $this->db->prepare("UPDATE `users` SET `password` = ? WHERE `id` = ?");
$query->bindValue(1, $password_hash);
$query->bindValue(2, $user_id);
try{
$query->execute();
return true;
} catch(PDOException $e){
die($e->getMessage());
}
}
public function recover($email, $generated_string) {
if($generated_string == 0){
return false;
}else{
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `generated_string` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $generated_string);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
global $bcrypt;
$username = $this->fetch_info('username', 'email', $email); // getting username for the use in the email.
$user_id = $this->fetch_info('id', 'email', $email);// We want to keep things standard and use the user's id for most of the operations. Therefore, we use id instead of email.
$charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$generated_password = substr(str_shuffle($charset),0, 10);
$this->change_password($user_id, $generated_password);
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = 0 WHERE `id` = ?");
$query->bindValue(1, $user_id);
$query->execute();
mail($email, 'Your password', "Hello " . $username . ",\n\nYour your new password is: " . $generated_password . "\n\nPlease change your password once you have logged in using this password.\n\n-Example team");
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
}
public function fetch_info($what, $field, $value){
$allowed = array('id', 'country', 'money', 'flag', 'email'); // I have only added few, but you can add more. However do not add 'password' eventhough the parameters will only be given by you and not the user, in our system.
if (!in_array($what, $allowed, true) || !in_array($field, $allowed, true)) {
throw new InvalidArgumentException;
}else{
$query = $this->db->prepare("SELECT $what FROM `users` WHERE $field = ?");
$query->bindValue(1, $value);
try{
$query->execute();
} catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchColumn();
}
}
public function confirm_recover($email){
$username = $this->fetch_info('username', 'email', $email);// We want the 'id' WHERE 'email' = user's email ($email)
$unique = uniqid('',true);
$random = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),0, 10);
$generated_string = $unique . $random; // a random and unique string
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = ? WHERE `email` = ?");
$query->bindValue(1, $generated_string);
$query->bindValue(2, $email);
try{
$query->execute();
mail($email, 'Recover Password', "Hello " . $username. ",\r\nPlease click the link below:\r\n\r\nhttp://www.example.com/recover.php?email=" . $email . "&generated_string=" . $generated_string . "\r\n\r\n We will generate a new password for you and send it back to your email.\r\n\r\n-- Example team");
} catch(PDOException $e){
die($e->getMessage());
}
}
public function user_exists($username) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function email_exists($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ?");
$query->bindValue(1, $email);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function register($username, $password, $email, $country, $timezone, $dst){
global $bcrypt; // making the $bcrypt variable global so we can use here
$date = date( 'Y-m-d' );
$ip = $_SERVER['REMOTE_ADDR']; // getting the users IP address
$email_code = $email_code = uniqid('code_',true); // Creating a unique string.
$password = $bcrypt->genHash($password);
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `country`, `timezone`, `dst`, `ip`, `regdate`, `email_code`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $country);
$query->bindValue(5, $timezone);
$query->bindValue(6, $dst);
$query->bindValue(7, $ip);
$query->bindValue(8, $date);
$query->bindValue(9, $email_code);
try{
$query->execute();
mail($email, 'Please activate your account', "Hello " . $username. ",\r\nThank you for registering with us. Please visit the link below so we can activate your account:\r\n\r\nhttp://www.touringlegends.com/register.php?email=" . $email . "&email_code=" . $email_code . "\r\n\r\n-- Example team");
}catch(PDOException $e){
die($e->getMessage());
}
}
public function activate($email, $email_code) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `email_code` = ? AND `accountlevel` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $email_code);
$query->bindValue(3, 0);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
$query_2 = $this->db->prepare("UPDATE `users` SET `accountlevel` = ? WHERE `email` = ?");
$query_2->bindValue(1, 1);
$query_2->bindValue(2, $email);
$query_2->execute();
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function email_confirmed($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ? AND `accountlevel` >= ?");
$query->bindValue(1, $email);
$query->bindValue(2, 1);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function login($email, $password) {
global $bcrypt; // Again make get the bcrypt variable, which is defined in init.php, which is included in login.php where this function is called
$query = $this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `email` = ?");
$query->bindValue(1, $email);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password']; // stored hashed password
$id = $data['id']; // id of the user to be returned if the password is verified, below.
if($bcrypt->verify($password, $stored_password) === true){ // using the verify method to compare the password with the stored hashed password.
return $id; // returning the user's id.
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
public function userdata($id) {
$query = $this->db->prepare("SELECT * FROM `users` WHERE `id`= ?");
$query->bindValue(1, $id);
try{
$query->execute();
return $query->fetch();
} catch(PDOException $e){
die($e->getMessage());
}
}
public function get_users() {
$query = $this->db->prepare("SELECT * FROM `users` ORDER BY `time` DESC");
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchAll();
}
}
init.php:
<?php
session_start();
require($_SERVER['DOCUMENT_ROOT'].'/core/connect/database.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/users.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/general.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/bcrypt.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/garage.php');
// error_reporting(0);
$users = new Users($db);
$general = new General();
$bcrypt = new Bcrypt(12);
$errors = array();
if ($general->logged_in() === true) {
$user_id = $_SESSION['id'];
$user = $users->userdata($user_id);
}
ob_start();
Here is the js loading the files (its a bit weird because its reloading jscrollpane, but working fine with html and php that dosent need external classes):
// Ajax
$(function () {
var api = $("#garagecontent").jScrollPane().data('jsp');
var reinitialiseScrollPane = function()
{
api.reinitialise();
}
// attaching click handler to links
$(document).on('click', '#garagecontainer a[href]', function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#garagecontent');
$wrap
// removing old data
api.getContentPane()
// load the remote page
.load(href, reinitialiseScrollPane , function (){
}
);
});
});
I have narrowed it down to users.php because it will work when I remove it from the includes (and its functions in init.php).
Can anyone spot what is breaking my code?
The solution to this question was using an autoloader. The page was breaking because of duplicate classes being called. My fault for having errors disabled i guess.

Check if user exists in database

I've made a user class which validates the data passed through the form and then subsequently updates the database table users. I want to add extra functionality such as checking if the username and email exists in the table, I've added a little script however it doesn't seem to be working.
I inserted a duplicated email address and I did not get the error message "email exists" instead I get the success message "1 row inserted":
Am I doing something wrong below? Is there perhaps a better way to approach this?
public function insert() {
if (isset($_POST['submit'])) {
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
$result = $this->mysqli->prepare("SELECT * FROM users WHERE email='".$email."'");
if ($result->num_rows) {
echo "email exisits!";
}
else
{
$stmt = $this->mysqli->prepare("INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssss', $username, $password, $name, $email); // bind strings to the paramater
//escape the POST data for added protection
$username = isset($_POST['username']) ? $this->mysqli->real_escape_string($_POST['username']) : '';
$cryptedPassword = crypt($_POST['password']);
$password = $this->mysqli->real_escape_string($cryptedPassword);
$name = isset($_POST['name']) ? $this->mysqli->real_escape_string($_POST['name']) : '';
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
}
You are using the worst API you ever can choose.
With safeMysql it would be
$exists = $this->db->getOne("SELECT 1 FROM users WHERE email=?s", $_POST['email']);
if ($exists) {
echo "email exisits!";
}
With PDO it is slightly longer but usable
$stmt = $this->db->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
if ($exists)
{
echo "email exisits!";
}
But with raw mysqli you will need a screenful of code only to check if user exists.
So, the whole function using safeMysql would be
public function insert()
{
if (!isset($_POST['submit'])) {
return FALSE;
}
$sql = "SELECT 1 FROM users WHERE email=?s";
$exists = $this->db->getOne($sql, $_POST['email']);
if ($exists)
{
echo "email exisits!";
return FALSE;
}
$sql = "INSERT INTO users SET ?u";
$allowed = array('username', 'name', 'email');
$insert = $this->db->filterArray($_POST, $allowed);
$insert['password'] = crypt($_POST['password']);
$this->db->query($sql, $insert);
return $this->db->afectedRows();
}
you need to use this code after prepare statement
$stmt->execute();
$stmt->store_result();
put this
if ($result->num_rows > 0) {
echo "email exisits!";
}
instead of
if ($result->num_rows) {
echo "email exisits!";
}
First, you are using prepare (great!) but then you are just passing in the value of email, effectively defeating the benefit of prepared statements.
Second, you never execute the query, which is why you don't get anything in num_rows.
public function insert() {
$result = $this->mysqli->prepare("SELECT COUNT(*) FROM users WHERE email=?");
$result->bind_param("s", $_POST['email']);
$result->execute();
$result->bind_result($email_count);
if ($email_count) {
echo "email exisits!";
} else {
# your other logic
From what I can see you're not assigning a value to num_rows prior to testing it with if ($result->num_rows), so it will always be 0

PDO get user_id

Okey, i have some trouble with my Login code..All work's great ,but when i try to get the row from my secound user ,it show me the row from the first user (i mean the information about the username,password,email,...).
public function login($username, $password){
global $pdo;
$query = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->execute();
$result = $query->rowCount();
if($result === 1){
return true;
} else {
return false;
}
}
I can't use mysql_result,but how i can get it like this ?
function user_id_from_username($username){
return mysql_result(mysql_query("SELECT user_id FROM users WHERE username = $username"), 0, 'user_id');
}
function login($username, $password){
$user_id = user_id_from_username($username);
return (mysql_result(mysql_query("SELECT COUNT(user_id) FROM users WHERE username = $username AND password = $password "),0) == 1)? $user_id : false;
}
Sorry for my englsih ^^
public function login($username, $password){
global $pdo;
$query = $pdo->prepare("SELECT id FROM users WHERE username = ? AND password = ?");
$query->execute(array($username, $password));
return $query->fetchColumn();
}

Categories