How to create a SELECT statement that recognizes trim($_POST['First_Name']) - php

// Create Your Variables
$First_Name = trim($_POST['First_Name']);
$Last_Name = trim($_POST['Last_Name']);
$Party_Size = trim($_POST['Party_Size']);
$Telephone = trim($_POST['Telephone']);
// Validate the Telephone Number before inserting into MySQL
if(!preg_match("/^[0-9]{3}-[0-9]{3}-[0-9]{4}$/", $Telephone)) {
echo "Please go back and enter a valid Telephone number using dashes.";
// Stop the Script if the Regular Expression does not match our sequence in the Database.
exit;
}
The problem is below. When I check if the user exists in the database the script works but if you add spaces it doesn't match the existing record in the database. Any suggestions?
$check = "SELECT * FROM Weddings WHERE First_Name = '$_POST[First_Name])' AND Last_Name = '$_POST[Last_Name])'";
$results = mysqli_query($mysqli, $check);
$data = mysqli_fetch_array($results, MYSQLI_ASSOC);
if ($data > 1) {
echo "You are already in our database. Someone will contact you soon.";
exit;
}

$firstname = mysqli_real_escape_string($mysqli, $_POST['First_Name']);
$lastname = mysqli_real_escape_string($mysqli, $_POST['Last_Name']);
$check = "SELECT * FROM Weddings WHERE First_Name LIKE '%{$firstname}%' AND Last_Name LIKE '%{$lastname}%'";
$results = mysqli_query($mysqli, $check);
$data = mysqli_fetch_array($results, MYSQLI_ASSOC);
if ($data > 1) {
echo "You are already in our database. Someone will contact you soon.";
exit;
}
As you can see, I added two extra lines that were suggested by geoffrey.
mysqli_real_escape_string - Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection.
Whenever you are allowing your users to enter some data that will be used in a query, you always should escape that data before executing the query. Not every user is a friendly user. If a user has knowledge about SQL injection attack, he can easily type some parts of SQL that will enable him to do something that you don't want.
For example, let's say user entered John as the first name and Doe as the last name. When combined with the query, it looks like this SELECT * FROM Weddings WHERE First_Name LIKE 'John' AND Last_Name LIKE 'Doe'. Nothing wrong with it.
But, what if user enters 1' OR '1' = '1 as the first name and as the last name. Then when combined with the query it will look like this SELECT * FROM Weddings WHERE First_Name LIKE '1' OR '1' = '1' AND Last_Name LIKE '1' OR '1' = '1'. Once executed, it will return all rows in your table. Learn more about SQL injection.

Just realised the other answer posted here is incorrect, it performs a like query which is not the OP's intent. The below answer trims any leading or trailing whitespace from the posted values, escapes them for security, and then performs an exact match on them. By default MySQL performs case insensitive searches and as such the case of the name will not matter.
$firstname = mysqli_real_escape_string($mysqli, trim($_POST['First_Name']));
$lastname = mysqli_real_escape_string($mysqli, trim($_POST['Last_Name']));
$check = "SELECT * FROM Weddings WHERE First_Name = '$firstname' AND Last_Name = '$lastname'";
$results = mysqli_query($mysqli, $check);
if (mysqli_num_rows($results) > 0) {
echo "You are already in our database. Someone will contact you soon.";
exit;
}
Please note that using someone's full name to check for existence is not reliable, it is better to use something that is unique such as their email address.

There are two issues with the script. The posted data is tainted until you check that you're getting from the user what you expect. At this point, the user could enter a first name of "123". So, it should be checked for being alphabetical and the surname should be checked for being alphabetical and the possibility of an apostrophe or a hyphen, so a last name like "O'Reilly" as well as "Smith-Jones" is accepted, as follows:
<?php
$fname = $lname = "";
// check for tainted data
if (ctype_alpha($_POST['First_Name'])) {
$fname = trim($_POST['First_Name']);
}
if ( preg_match("/^[a-zA-Z'-]+$/, $_POST['Last_Name']) ) {
$lname = trim($_POST['Last_Name']);
}
Once, the data validates, then it is appropriate to pass data to trim() to remove superfluous space characters, such as a blank space, tab, newline, etc.
The second issue is making sure that the query is not vulnerable to SQL injection.
<?php
if (strlen($fname) > 0 && strlen($lname) > 0) {
$firstname = mysqli_real_escape_string($link, trim($fname));
$lastname = mysqli_real_escape_string($link, trim($fname));
$query = "SELECT * FROM Weddings WHERE First_Name = '$firstname' AND Last_Name = '$lastname'";
$results = mysqli_query($link, $query or die( mysqli_error($link) ) );
if (mysqli_num_rows( $results ) > 0) {
echo "You are already in our database. Someone will contact you soon.";
exit;
}
mysqli_close($link);
}
The problem tho' has not been adequately resolved as you can still get around mysqli_real_escape_string() if you're a hacker. Per the Manual:
The character set must be set either at the server level, or with the
API function mysqli_set_charset() for it to affect
mysqli_real_escape_string().
This article offers further insight. So, it is actually better to use prepared statements., as follows:
<?php
$dbh = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');
$stmt = $dbh->prepare("SELECT * FROM Weddings WHERE First_Name = ? AND Last_Name = ?");
if ($stmt->execute( array( $fname,$lname))) {
$row = $stmt->fetch(PDO::FETCH_ASSOC));
if ($row !== FALSE){
echo "You are already in our database. Someone will contact you soon.";
}
}

Related

Select two different columns from the same row using two different queries

I want to run two queries at a time in a function to verify the username and email separately when registering. If one of them already exists in the database, it will return the correct error message on the form.
I investigate them separately so that they can be linked to two separate messages based on a query.
If the username already exists in the database, display the corresponding message. If I put them in a single query, then the separate investigation cannot be done.
My error is: It does not allow you to run two queries at the same time and throws the following error: there is a problem with the preceding parameter. Or it returns an incorrect value.
function pl($connection) {
$query = "SELECT username FROM users WHERE username = ?";
$query2 = "SELECT email FROM users WHERE email = ?";
if ($statment = mysqli_prepare($connection, $query) && $statment2 = mysqli_prepare($connection, $query2)) {
mysqli_stmt_bind_param($statment, "s", $_POST['usern']);
mysqli_stmt_execute($statment);
$result = mysqli_stmt_get_result($statment);
$record = mysqli_fetch_assoc($result);
mysqli_stmt_bind_param($statment2, "s", $_POST['email']);
mysqli_stmt_execute($statment2);
$result2 = mysqli_stmt_get_result($statment2);
$record2 = mysqli_fetch_assoc($result2);
}
if ($result != null) {
echo "succes";
//it will enter even if there is an error
}
}
How it could be solved to execute two mysqli_prepare() at a time?
Why you do not use one query?
Something like:
$query = "SELECT username, email FROM users WHERE username = ? and email = ?";
$statment = mysqli_prepare($connection, $query);
mysqli_stmt_bind_param($statment, "ss", $_POST['usern'], $_POST['email']);
mysqli_stmt_execute($statment);
$result = mysqli_stmt_get_result($statment);
$record = mysqli_fetch_assoc($result);
if (!$record) {
echo "succes";
//it will enter even if there is an error
}
also you miss the } at end of your first if

How come my script can't check the database for similar usernames? [duplicate]

This question already has answers here:
How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)
(4 answers)
Closed 3 years ago.
I'm trying to check the database for a taken username when the user signs up. The connection to the database works fine as a similar password will be added to the table.
$username = $_POST['user'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
$s = 'SELECT * FROM users WHERE username = "$username"';
$result = mysqli_query($con, $s);
$num = mysqli_num_rows($result);
if ($num == 1) {
echo "Username is taken";
}else {
table for users
It goes to the else and adds the username to the database anyways. I have checked to make sure there isn't more than one username, although a greater than sign would work better anyway. any ideas?
Your code must be using parameter binding to send the value of $username to the database, otherwise "$username" is treated as a literal string. It will also protect your from SQL injections.
It would probably be better to create a UNIQUE key on that column instead. If you want to do it in the application layer for whatever reason, you can fetch the result and use that.
$stmt = $con->prepare('SELECT * FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result()->fetch_all();
if ($result) {
echo "Username is taken";
} else {
// No such username in the database yet
}
This is not going to be very efficient, so we can simplify it using COUNT(1). It will return a single value containing the number of matching rows.
$stmt = $con->prepare('SELECT COUNT(1) FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$usernameTaken = $stmt->get_result()->fetch_row()[0];
if ($usernameTaken) {
echo "Username is taken";
} else {
// No such username in the database yet
}
For more explanation see https://phpdelusions.net/mysqli/check_value
$s = 'SELECT * FROM users WHERE username = "$username"';
You are using double quote inside single quote so there is no interpolation happening. Change the order to
$s = "SELECT * FROM users WHERE username = '{$username}'";

Why is my mysqli_fetch_assoc not grabbing the row info so I can insert details into my table?

First off, I know about sql injection and that my code is not foolproof, prone to injection etc. Will be working on that next.
Now : from my Android app to my PHP file I submit a JSON array of phone numbers like :
[{"phone_number":"+12345678"},
{"phone_number":"+23456789"},
{"phone_number":"34567890"},
{"phone_number":"45678901"}
etc... etc...
These are contacts in my app user's phone. If these contacts are people who are also users of my app then I want to insert those numbers into my contacts table.
But I can't get it to work. mysqli_fetch_assoc isn't working correctly. I don't know why.
In my contacts table I have 3 columns - an auto increment, user_id and contact_id. The first two values are inserted correctly but the contact_id is always put in as '0', which is wrong.
Here is my code :
require('dbConnect.php');
//this is me, +567890123, my user_id in the user table
$user_id = '20';
//post all contacts in my phone as a JSON array
$json = $_POST['phonenumber'];
$array = json_decode($json);
foreach ($array as $value) {
$phonenumber = $value->phone_number;
$sql = "SELECT username FROM user WHERE username = '$phonenumber'";
$result = mysqli_query($con, $sql);
$num_rows = mysqli_num_rows($result);
if ($num_rows > 0) {
echo "phonenumber is " . $phonenumber . "<br>";
// we want to put $phonenumber in the contacts table, as one of +567890123 contacts
// In the user table get the associated rows of $phonenumber
while ($row = mysqli_fetch_assoc($result)) {
// get the associated user_id in that row, that's what we want to put into the contacts table
$contact_id = $row['user_id'];
$insert_into_contacts_command = "INSERT INTO contacts VALUES(NULL, '$user_id','$contact_id')";
$insert_into_contacts_table = mysqli_query($con, $insert_into_contacts_command);
}
} //if +353864677745 is NOT in the user table...
else {
echo 'not a match.';
}
}
$contact_id = $row['user_id'];
Here $contact_id will be null, because you are trying to access not existing field $row['user_id'] of the $row .
Actually there is only one field username in your results set, as you specified:
$sql = "SELECT username FROM user WHERE username = '$phonenumber'";
Try to change your query to this:
$sql = "SELECT user_id, username FROM user WHERE username = '$phonenumber'";
Your query selects the column username, not userid.
You haven't posted anything about the table user, so it's hard to suggest a new query, but I guess it's the following:
$stmt = mysqli_prepare($con, "SELECT userid FROM user WHERE username = ?");
$stmt->bind_param("s", $phonenumber);
$stmt->execute();
$stmt->bind_result($userid);
while ($stmt->fetch()) {
// Work with $userid
}
You'll note that this uses a prepared statement with a bound parameter. That way, your code is not prone to SQL injections.

Comparing data in database in PHP

What I'm trying to do is saving some data in the database and when user will press "SAVE" button script will compare the data entered by the user with data already present in the database. If the data matches it will show a warning that is "The entered data is already in the database please use search bar to search it." In my case I only want it to check phone number and cnic (cnic = national identity card number). Here is what I am doing.
<?php include_once("config.php"); // mysql_connect and database selection are in this file.
$name = $_POST['name']; // data coming from save_info.php
$gender = $_POST['option']; // data coming from save_info.php
$cnic = $_POST['cnic']; // data coming from save_info.php
$number = $_POST['number']; // data coming from save_info.php
$address = $_POST['address']; // data coming from save_info.php
$info = $_POST['info']; // data coming from save_info.php
$check = "SELECT * FROM info WHERE num = $number AND cnic = $cnic"; // checking data
$cresult = mysql_query($check);
if (mysql_num_rows($cresult)==1) {
echo "The entered phone number/cnic is already in the database, Please use search bar to search it.";
header('refresh:10;url=save_info.php');
}
else
{
$sql = "INSERT INTO info(name, gender, cnic, num, address, info)VALUES('$name', '$gender', '$cnic', '$number', '$address', '$info')";
$result = mysql_query($sql);
mysql_close();
header('Location:saved_info.php');
}
?>
You probably missed the quotes in your query:
$check = "SELECT * FROM info WHERE num = \"$number\" AND cnic = \"$cnic\"";
Since the fields are probably textual (varchar or something like that) you need to tell where the limits of the values you're comparing to are.
Also if you need to skip the saving if any of the values matches you should use OR:
$check = "SELECT * FROM info WHERE num = \"$number\" OR cnic = \"$cnic\"";
Try to add single quotes around your parameters and rewrite the query like this..
$check = "SELECT * FROM `info` WHERE `num` = '$number' OR cnic='$cnic'";
Also, on your if statement.. check like this
if (mysql_num_rows($cresult)>0) {
Also, stop using mysql_* functions as they are deprecated. Switch to MySQLi or PDO instead.

SELECT query trouble - user login system

I am just trying to write a simple script that verifies the username and password of a user that has attempted to login...and then starts a session. However, I am running into some trouble.
When I try to run the script below, SUCCESS does not print out. As if the username and password is incorrect, however, I know for a fact that the username and passwords entered are, in fact, correct.
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM users WHERE username='.$username.' AND password='.$password.'");
while($row = mysql_fetch_array($result)){
echo 'SUCCESS';
}
When I try to run the script below however, success prints out twice (which is the number of sample users I have in my db so far), which is correct.
I am guess I have a problem with the AND mySQL query above, however, it seems correct to me... is there a problem with my first query above? if not, than what else might be the problem?
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM users");
while($row = mysql_fetch_array($result)){
echo 'SUCCESS';
}
You're parsing variables, not concatenating them, you don't need the ..
"SELECT * FROM users WHERE username='$username' AND password='$password'"
username is a protected keyword, try this:
$result = mysql_query("SELECT * FROM `users` WHERE `username`='$username' AND `password`='$password'");
Ignoring the gaping SQL injection vulnerability, you're constructing your query string incorrectly:
$result = mysql_query("SELECT * FROM users WHERE username='.$username.' AND password='.$password.'");
^ ^
You're still in "string mode" where the indicated periods are (and for the password section too), so you're embedding literal periods into your query string, instead of doing string concatenation.
Remote the periods, and you'll be better off (but still vulnerable to sql injection):
$result = mysql_query("SELECT * FROM users WHERE username='$username' AND password='$password'");
Try this instead:
$result = mysql_query("SELECT * FROM users WHERE username=\"$username\" AND password=\"$password\"");
Obviously, this isn't a great way of inserting data. You should look at mysqli to insert data as a minimum.
try this line instead:
$result = mysql_query("SELECT * FROM `users` WHERE `username`='".$username."' AND `password`='".$password."'");
Notice the extra "'s I've added in. before it was looking for '.$username.'

Categories