I'm a newbie with PHP. I am trying to create a log in /register system for a project, so I am using a login system source code I found which has many functions and features like salted passwords. The system itself works fine, but I am trying to add more fields to my MySQL Table. The system had an array for extra columns, but I think it was resulting in bad mysql syntax so I decided to write out the query myself using the variables, but I am not sure how I can give access to the variables to the function. The variables are in the register.php document, here is the code (all of register.php):
if( isset($_POST['submit']) ){
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$user = $_POST['username'];
$sex = $_POST['sex'];
$country = $_POST['strCountryChoice'];
$email = $_POST['email'];
$pass = $_POST['pass'];
$pass2 = $_POST['pass2'];
$birthdate = $_POST['birthdate'];
$created = date("Y-m-d H:i:s");
//need to add a lot more validation functions.. AKA Check if email exists and username. Password > 5 chars
if( $user=="" || $email=="" || $pass=='' || $pass2=='' || $firstname=='' || $lastname='' || $sex='' || $country='' || $birthdate='' ){
echo "Fields Left Blank","Some Fields were left blank. Please fill up all fields.";
exit;
}
if( !$LS->validEmail($email) ){
echo "E-Mail Is Not Valid", "The E-Mail you gave is not valid";
exit;
}
if( !ctype_alnum($user) ){
echo "Invalid Username", "The Username is not valid. Only ALPHANUMERIC characters are allowed and shouldn't exceed 10 characters.";
exit;
}
if($pass != $pass2){
echo "Passwords Don't Match","The Passwords you entered didn't match";
exit;
}
$createAccount = $LS->register($user, $pass,
array(
"email" => $email,
"name" => $firstname,
"lastname" => $lastname,
"gender" => $sex,
"country" => $country,
"DOB" => $birthdate,
"created" => date("Y-m-d H:i:s") // Just for testing
)
);
if($createAccount === "exists"){
echo "User Exists.";
}elseif($createAccount === true){
echo "Success. Created account.";
}
}
The whole system takes place in another file which has the class. Here is the register function:
public function register( $id, $password, $other = array() ){
if( $this->userExists($id) && (isset($other['email']) && $this->userExists($other['email'])) ){
return "exists";
}else{
$randomSalt = $this->rand_string(20);
$saltedPass = hash('sha256', "{$password}{$this->passwordSalt}{$randomSalt}");
if( count($other) == 0 ){
/* If there is no other fields mentioned, make the default query */
//old query: ("INSERT INTO `{$this->dbtable}` (`username`, `password`, `password_salt`) VALUES(:username, :password, :passwordSalt)");
//new query: ("INSERT INTO `{$this->dbtable}` (`username`, 'email' , `password`, `password_salt` , 'name' , 'lastname' , 'gender' , 'country' , 'DOB') VALUES(:username, :email, :pass, :passwordSalt, :firstname, :lastname, :gender, :country, :DOB)");
$sql = $this->dbh->prepare("INSERT INTO `{$this->dbtable}` (`username`, `password`, `password_salt`) VALUES(:username, :password, :passwordSalt)");
}else{
/* if there are other fields to add value to, make the query and bind values according to it */
//old query: ("INSERT INTO `{$this->dbtable}` (`username`, `password`, `password_salt`, $columns) VALUES(:username, :password, :passwordSalt, :$colVals)");
//new query: ("INSERT INTO `{$this->dbtable}` (`username`, 'email' , `password`, `password_salt` , 'name' , 'lastname' , 'gender' , 'country' , 'DOB') VALUES(:username, :email, :pass, :passwordSalt, :firstname, :lastname, :gender, :country, :DOB)");
$keys = array_keys($other);
$columns = implode(",", $keys);
$colVals = implode(",:", $keys);
//l= $this->dbh->prepare("INSERT INTO `{$this->dbtable}` (`username`, `password`, `password_salt`, $columns) VALUES(:username, :password, :passwordSalt, :$colVals)");
//INSERT INTO MyGuests (firstname, lastname, email)cLUES ('John', 'Doe', 'john#example.com')
$sql = $this->dbh->prepare("INSERT INTO `{$this->dbtable}` (username,email,password,password_salt,name,lastname,created,gender,country,DOB) VALUES ('$username','$email','$pass','$saltedPass','$firstname','$lastname','$created','$gender','$country','$birthdate')");
print($sql);
foreach($other as $key => $value){
$value = htmlspecialchars($value);
$sql->bindValue(":$key", $value);
}
}
/* Bind the default values */
$sql->bindValue(":username", $id);
$sql->bindValue(":password", $saltedPass);
$sql->bindValue(":passwordSalt", $randomSalt);
$sql->execute();
return true;
}
}
So I need to use the variables from register.php in the class file. Can I just include it at the top or do I need to do something specific to the function?
Thanks. I'm focusing on the $sql line after else.
Yes you can include/require register.php file in the class file to use all the variables.
On another note i would like to mention that you should always filter out the POST data before adding it to the query for security concerns.
Related
I want to insert some data into a table using PDO. I looked for some examples and I found that I need to use the functions prepare, bind and then execute, however I can not figure out in my code what I am doing wrong because it inserted nothing and I have no error in the query or php code.
if($_POST){
$account = $_POST['account'];
$password = $_POST['password'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$stmt = 'INSERT INTO employer(account, password, phone, email) VALUES(:account, :password, :phone, :email)';
$stmt = $conn->prepare($stmt);
$stmt->bindParam(':account', $account, PDO::PARAM_STR,100);
$stmt->bindParam(':password',$password, PDO::PARAM_STR,100);
$stmt->bindParam(':phone', $phone, PDO::PARAM_STR,100);
$stmt->bindParam(':email', $email, PDO::PARAM_STR,100);
if ($stmt->execute(array('account' => $account,
'password' => $password,
'phone' => $phone,
'email' =>$email
)
)
){
echo "success";
}else{
echo "error";
}
}
Error detected by #jeroen I was binding twice. So I can bind "either bind before the execute statement or send an array as a parameter, not both"
$stmt = $pdo->prepare('
INSERT INTO employer
(account, password, phone, mail)
values (:account, :password, :phone, :mail)');
$stmt->execute(
array(':account' => $account,
':password' => md5($password),
':phone' => $phone,
':mail' => $email
)
);
if ($pdo->lastInsertId())
return true;
else
return false;
I sanitise the data I receive from the form in the following way:
$gender = filter_var($_POST['gender'], FILTER_SANITIZE_STRING);
$firstName = filter_var($_POST['firstName'], FILTER_SANITIZE_STRING);
$lastName = filter_var($_POST['lastName'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
$message = filter_var($_POST['comment'], FILTER_SANITIZE_STRING);
$address = filter_var($_POST['address'], FILTER_SANITIZE_STRING);
$numBrochures = (int) filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT);
The relevant SQL queries that insert the data are as follows:
if (mysqli_query($conn, "INSERT INTO users(firstName, lastName, email, gender) VALUES('$firstName', '$lastName', '$email', '$gender')") == TRUE) {
logSuccess($file, "Adding user");
}
else {
logError($file, "Adding user", mysqli_error($conn));
}
$userId = $conn->query("SELECT `userId` FROM users WHERE `firstName` = '$firstName' AND `lastName` = '$lastName' AND `email` = '$email'")->fetch_object()->userId;
if ($userId == false) {
logError($file, "Fetching user id", mysqli_error($conn));
}
if (mysqli_query($conn, "INSERT INTO brochureOrders(userId, address, numBrochures, message) VALUES('$userId', '$address', '$numBrochures', '$message')") == TRUE) {
logSuccess($file, "Brochure Order");
$sendConfirmationEmail = true;
}
else {
logError($file, "Brochure Order", mysqli_error($conn));
}
However, in my database, I see entries like the following:
address = "vz8y8E gghwptvvzuak, [url=http://ytvsmximkjnp.com/]ytvsmximkjnp[/url], [link=http://hiabgyvsjifp.com/]hiabgyvsjifp[/link], http://tyvylndqitoy.com/"
Shouldn't the following have taken care of this?
$address = filter_var($_POST['address'], FILTER_SANITIZE_STRING);
Could someone tell me what I am doing incorrectly here?
Because the OP stated in the comments he wants to switch to prepared statement, I thought I'd show him an example.
Instead of something like this:
if (mysqli_query($conn, "INSERT INTO users(firstName, lastName, email, gender) VALUES('$firstName', '$lastName', '$email', '$gender')") == TRUE) {
logSuccess($file, "Adding user");
}
else {
logError($file, "Adding user", mysqli_error($conn));
}
Do something like this:
$query = "INSERT INTO users (firstName, lastName, email, gender) VALUES(?, ?, ?, ?)";
if($stmt = $mysqli->prepare($query)){
$stmt->bind_param('ssss', $firstName, $lastName, $email, $gender);
$stmt->exeucte();
$stmt->close();
}else die("Failed to prepare!");
and this
$query = "SELECT `userId` FROM users WHERE `firstName` = ? AND `lastName` = ? AND `email` = ?";
if($stmt = $mysqli->prepare($query)){
$stmt->bind_param('sss', $firstName, $lastName, $email);
$stmt->execute();
$stmt->bind_result($userId);
$stmt->fetch();
$stmt->close()
}else die("Failed to prepare!");
How do I check if all POST data are NOT EMPTY?
Below is my code. This allows to INSERT data even when there are blank fields.
$stname = $_POST['stname'];
$staddress = $_POST['staddress'];
$stbirth = $_POST['bday'];
$tel = $_POST['tel'];
$email = $_POST['email'];
if(isset($_POST['stname'] && $_POST['staddress'] && $_POST['bday'] && $_POST['tel'] && $_POST['email'])) {
$sql = "INSERT INTO student (Student_Name, Address, Birthday, Telephone, Email) VALUES (:name, :address, :bday, :tel, :email)";
$statement = $con_db->prepare($sql);
$statement->execute(array('name' => $stname, 'address' => $staddress, 'bday' => $stbirth, 'tel' => $tel, 'email' => $email));
if($statement){
echo "Successful!";
} else {
echo "Error occured...";
};
} else {
echo "You did not fill out the required fields.";
}
I even tried the below. Did not work. What might be the issue?
if(isset($_POST['stname'] , $_POST['staddress'] , $_POST['bday'] , $_POST['tel'] , $_POST['email']))
Change the IF statement and use the variable which you already have assigned. The isset should only have one variable inside of it. Because otherwise you create a new expression which will always be set and will therefore return TRUE.
$stname = $_POST['stname'];
$staddress = $_POST['staddress'];
$stbirth = $_POST['bday'];
$tel = $_POST['tel'];
$email = $_POST['email'];
if($stname != '' && $staddress != '' && $stbirth != '' && $tel != '' && $email != '') {
$sql = "INSERT INTO student (Student_Name, Address, Birthday, Telephone, Email) VALUES (:name, :address, :bday, :tel, :email)";
$statement = $con_db->prepare($sql);
$statement->execute(array('name' => $stname, 'address' => $staddress, 'bday' => $stbirth, 'tel' => $tel, 'email' => $email));
if($statement){
echo "Successful!";
} else {
echo "Error occured...";
};
} else {
echo "You did not fill out the required fields.";
}
In isset you should not use &&. Try this..
if(isset($_POST['stname'] , $_POST['staddress'] , $_POST['bday'] , $_POST['tel'] , $_POST['email'])
and !empty($_POST['stname']) and !empty($_POST['staddress']) and !empty($_POST['bday']) and
!empty($_POST['tel']) and !empty($_POST['email'])
){
//Your codes
}
I have this validation code:
<?php
$con=mysql_connect("localhost","root","");
mysql_select_db("nnx",$con);
$tbl=mysql_query("SELECT * FROM tablename");
while($row=mysql_fetch_array($tbl))
{
$name=$_POST['name'];
$lname=$_POST['lname'];
$add=$_POST['add'];
$age=$_POST['age'];
$contact=$_POST['contact'];
$email=$_POST['email'];
$user=$_POST['user'];
$pass=$_POST['pass'];
if(($name!="")&&($lname!="")&&($add!="")&&($age!="")&&($contact!="")&& ($email!="")&&($user!="")&&($pass!=""))
{
if ($_POST['user']==$row['username'])
{
header("location: /register.php?codeErr2=1");
}
else
{
$value=mysql_query("INSERT INTO tablename(name, lastname, address, age, contact,email, username, password) VALUES ('".$_POST['name']."','".$_POST['lname']."','".$_POST['add']."','".$_POST['age']."','".$_POST['contact']."','".$_POST['email']."','".$_POST['user']."','".$_POST['pass']."')");
}
}
else
{
header("location: /register.php?codeErr=1");
}
}
This validation is for my registration form, If all the fields are filled up it will check if the username that the user enters is already on the database or not, else, it will get an error message. If the username is already on the database, an error message will be outputted else it will proceed to the next page and all values will be inserted on the database. The problem is that whenever I enter the username which was already on the database, it still accepts the username. I can't find anything wrong with my validation code. Can someone help me out what could be the possible problem here? Thank you in advance. :)
You should check for username and die after the redirect:
$tbl=mysql_query("SELECT * FROM tablename WHERE `username` = '".mysql_real_escape_string($_POST['user'])."'");
$row = mysql_fetch_assoc($tbl);
if ($_POST['user'] == $row['username']){
header("location: /register.php?codeErr2=1");
die;
}
You code is SQL injection vulnerable:
$con=mysql_connect("localhost","root","");
mysql_select_db("nnx",$con);
$tbl=mysql_query("SELECT * FROM tablename WHERE `username` = '".mysql_real_escape_string($_POST['user'])."'");
$row = mysql_fetch_assoc($tbl);
if ($_POST['user'] == $row['username']){
header("location: /register.php?codeErr2=1");
die;
}
$name= $_POST['name'];
$lname= $_POST['lname'];
$add = $_POST['add'];
$age = $_POST['age'];
$contact = $_POST['contact'];
$email = $_POST['email'];
$user = $_POST['user'];
$pass = $_POST['pass'];
if(($name!="") && ($lname!="") && ($add!="") && ($age!="") && ($contact!="") && ($email!="") && ($user!="") && ($pass!="")){
$value=mysql_query("INSERT INTO tablename(name, lastname, address, age, contact, email, username, password)
VALUES
('".mysql_real_escape_string($name)."','".mysql_real_escape_string($lname)."','".mysql_real_escape_string($add)."','".mysql_real_escape_string($age)."',
'".mysql_real_escape_string($contact)."','".mysql_real_escape_string($email)."','".mysql_real_escape_string($user)."',
'".mysql_real_escape_string($pass)."')");
} else {
header("location: /register.php?codeErr=1");
die;
}
As a side note you should move to PDO or MySQLi as mysql_* functions are deprecated.
Here is a nice tutorial and here is an example:
$db = new PDO('mysql:host=localhost;dbname=nnx;charset=UTF-8', 'root', '', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION))
$stmt = $db->prepare("SELECT * FROM `tablename` WHERE `username` = :username");
$stmt->execute(array(':username' => $_POST['user']));
$row_count = $stmt->rowCount();
if($row_count){
header("location: /register.php?codeErr2=1");
die;
}
if(($name!="") && ($lname!="") && ($add!="") && ($age!="") && ($contact!="") && ($email!="") && ($user!="") && ($pass!="")){
$stmt = $db->prepare("INSERT INTO `tablename`(`name`, `lastname`, `address`, `age`, `contact`, `email`, `username`, `password`) VALUES (:name, :lname, :address, :age, :contact, :email, :username, :password)");
$stmt->execute(array(':name' => $_POST['name'], ':lname' => $_POST['lname'], ':address' => $_POST['add'], ':age' => $_POST['age'], ':contact' => $_POST['contact'], ':email' => $_POST['email'], ':username' => $_POST['user'], ':password' => $_POST['pass']));
} else {
header("location: /register.php?codeErr=1");
die;
}
This way your are sql injection free.
<?php
$con=mysql_connect("localhost","root","");
mysql_select_db("nnx",$con);
$name=$_POST['name'];
$lname=$_POST['lname'];
$add=$_POST['add'];
$age=$_POST['age'];
$contact=$_POST['contact'];
$email=$_POST['email'];
$user=$_POST['user'];
$pass=$_POST['pass'];
if(($name!="")&&($lname!="")&&($add!="")&&($age!="")&&($contact!="")&& ($email!="")&&($user!="")&&($pass!=""))
{
$tbl=mysql_query("SELECT * FROM tablename where username = '{$user}'");
$num_rows = mysql_num_rows($tbl);
if($num_rows > 0){
header("location: /register.php?codeErr2=1");
} else {
while($row=mysql_fetch_array($tbl))
{
$value=mysql_query("INSERT INTO tablename(name, lastname, address, age, contact,email, username, password) VALUES ('".$_POST['name']."','".$_POST['lname']."','".$_POST['add']."','".$_POST['age']."','".$_POST['contact']."','".$_POST['email']."','".$_POST['user']."','".$_POST['pass']."')");
}
}
} else {
header("location: /register.php?codeErr=1");
}
?>
hi i have a table in mysql have six fields
ID, mobileNumber, firstName, lastName, email, password , rollID
ID is autoincrement and i want to insert to it using php
php code
public function run($firstName, $lastName, $mobileNumber, $email, $password, $rePassword) {
if (!$this->db->isExistedMobile($mobileNumber)) {
try {
$query = "INSERT INTO user (firstName, lastName, mobileNumber, email, password, rollID)
VALUES (:firstName, :lastName, :mobileNumber, :email, :password, 'rollID')";
$sth = $this->db->prepare($query);
$sth->execute(array(
':firstName' => $firstName,
':lastName' => $lastName,
':mobileNumber' => $mobileNumber,
':email' => $email,
':password' => $password,
':rollID' => "roma"
));
header("location: " . URL . "index");
} catch (PDOException $e) {
die($e->getMessage());
exit;
}
} else {
include 'controlers/Error.php';
$error = new Error();
$error->index("you enterd a used mobile number");
}
}
i have this exception
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
the function isExistedMobile always return false so don't worry about it , i don't know where is the wrong , is it in the syntax ? or in the rollID cos i make it static ?
thank you for helping :)
The problem (with your original code) was that the parameter array had a trailing comma, which created an additional null element within it.
I'd recommend reverting to that version (with the literal value for rollID) as originally intended, but make sure you remove the trailing comma after $password:
public function run($firstName, $lastName, $mobileNumber, $email, $password, $rePassword) {
if (!$this->db->isExistedMobile($mobileNumber)) {
$query = "INSERT INTO user (firstName, lastName, mobileNumber, email, password, rollID)
VALUES (:firstName, :lastName, :mobileNumber, :email, :password, 'ddd')";
$sth = $this->db->prepare($query);
$sth->execute(array(
':firstName' => $firstName,
':lastName' => $lastName,
':mobileNumber' => $mobileNumber,
':email' => $email,
':password' => $password // , removed from here
));
header("location: " . URL . "index");
} else {
include 'controlers/Error.php';
$error = new Error();
$error->index("you enterd a used mobile number");
}
}