I have a login for my site. Below shows the registration page. The emailaddress is their username. How do create an error message alert if an # symbol and . has not been inserted into the username(emailaddress) field?
<?php
// Check if he wants to register:
if (!empty($_POST[emailaddress]))
{
// Check if passwords match.
if ($_POST[password] != $_POST[password2])
exit("Error - Passwords don't match. Please go back and try again.");
// Assign some variables.
$date = mktime("d - m - Y");
$ip = $_SERVER[REMOTE_ADDR];
require_once("config.php");
// Register him.
$query = mysql_query("INSERT INTO neworders
(emailaddress, firstname, surname, password, datereg, ip)
VALUES ('$_POST[emailaddress]','$_POST[firstname]','$_POST[surname]','$_POST[password]','$datereg','$ip')")
or die ("Error - Couldn't register user.");
echo "Welcome $_POST[username]! You've been successfully reigstered!<br /><br />
Please login <a href='login.php'><b>here</b></a>.";
exit();
}
?>
You should probably use a more robust solution to validate emails. Use PHP's filter_var() function with the FILTER_VALIDATE_EMAIL flag.
$validEmail = filter_var($email, FILTER_VALIDATE_EMAIL);
Of course, this is just for validating the email. If you're inserting it into a database, use that database's escape mechanism for strings or use bound queries.
Use the function at the bottom of this page:
http://www.linuxjournal.com/article/9585
You can check if a string has characters in it with the stristr() php function (This is not the ideal solution, but just very simply checks if characters in a string exist like you described. Using filter_var as described below is a better solution).
So to do what you are asking you could do something like:
if(!(stristr($_POST['emailaddress'], '#') && stristr($_POST['emailaddress'], '.')) {
echo 'Email not valid';
exit(1);
}
Something else you could do is use the prebuilt php filter_var function to do this: http://php.net/manual/en/function.filter-var.php
if(!filter_var($_POST['emailaddress'],FILTER_VALIDATE_EMAIL)) {
echo 'Email not valid';
exit(1);
}
You can also use regex pattern matching if you want. I would also advise to do some sort of cleaning (mysql_real_string_escape) on the $_POST['emailaddress'] field, if you are inserting it into a database.
Related
i have a login form that transmit the information to the php code in the same page but even the username and password are correct it always ignore him this is my php code:
$mail = test_input($_POST["email"]);
//check if the email address format is valid
if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
echo "<h3>Invalid email format</h3>";
}
$pass = trim($_POST["password"]);
$stmtn="SELECT first_name, email , password FROM `users` WHERE email= '$mail'";
$result = mysqli_query($connection,$stmtn);
$rows= mysqli_fetch_assoc($result);
if($rows && $rows['password']== md5($pass)){
session_start();
$_SESSION['username']=$rows['first_name'];
header("Location: index.php");
}else{
echo "<h3> Sorry! your email or password is incorrect </h3>";
echo "<h3> Please <strong><a href='login.php'>login</a></strong> again to your account </h3>";
echo var_dump($rows);
}
the statements in the else part always are executed and the result of the var_dump for the array $rows is equal to the information in the db exactly
and this is the code of the function test_input
<?php
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
Please stop using stripslashes, it's really not needed. Instead you should properly clean your user input using a filter_var or a regex.
After you've set the header() to redirect you should always and immediately set an exit statement to cease the script execution.
You really, REALLY should use parameterised queries with MySQLi to stop your SQL being abused and attacked (take a peak at this question just for a flavour of the layout of parameterised MySQLi)
Stop using md5. Now. if your PHP is above 5.3 you really, really should be using password_hash and password_verify for your and your users security. Good habits start at home.
Also don't trim user passwords. Don't make any changes to a password variable at all (until after they've been password_verifyed), because if I want to have " dickens !" as my password, why the hell shouldn't I?
With the above code changes in place there is no need for the test_input function at all on your script.
And there is no need to test_input on the email address because you validate it straight afterwards with filter_var. Inefficient.
Good luck.
i just want to add the ip address and the username after successful login this is my code. The problem is it did not continue to the profile after login but when i remove the insert query it continue to the profile what should i do ?
session_start();
if(isSet($_POST['username']) && isSet($_POST['password']))
{
// username and password sent from Form
$username=mysqli_real_escape_string($db,$_POST['username']);
$password=mysqli_real_escape_string($db,$_POST['password']);
$password=md5($password);
$result=mysqli_query($db,"SELECT PatientId FROM patient WHERE PatientId='$username' AND Password='$password'");
$count=mysqli_num_rows($result);
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1)
{
$_SESSION['PatientId']=$row['PatientId'];
echo $row['FirstName']. ' '.$row['LastName'];
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$query=mysqli_query($db,"insert into login_history_patient(PatientId,IP)Values('".$username.",'".$ip"')");
}
}
The first initial problem here, is that you're not checking for errors and assuming success right off the bat.
This line:
$query=mysqli_query($db,"insert into login_history_patient(PatientId,IP)
Values ('".$username.",'".$ip"')");
being modified to:
$query=mysqli_query($db,"insert into login_history_patient (PatientId,IP)
Values ('".$username.",'".$ip"')")
or die(mysqli_error($db));
would have signaled the syntax error.
http://php.net/manual/en/mysqli.error.php
Missing a concatenate '".$ip"' => '".$ip."'
You could have also used:
$result = mysqli_query($db, $query);
if (!$result)
{
throw new Exception(mysqli_error($db));
}
else{ echo "Success."; }
Ideally, using mysqli_affected_rows() will give you a better result, if the query truly was successful.
http://php.net/manual/en/mysqli.affected-rows.php
Plus, you're storing passwords using MD5 which is a very bad idea because it's old and considered broken, should this site go or is LIVE.
You should also use mysqli with prepared statements, or PDO with prepared statements.
For password storage, use CRYPT_BLOWFISH or PHP 5.5's password_hash() function.
For PHP < 5.5 use the password_hash() compatibility pack.
Your users will thank you for it.
Always use properly formatted queries like this:
SELECT * FROM login WHERE id = '" . $id . "';
The last query you are executing, is half properly formed (you're missing a dot):
$query=mysqli_query($db,"insert into login_history_patient(PatientId,IP)Values('".$username.",'".$ip."')");
The . was missing after the '".$ip"'
In any language syntax of Concatenation of string with variable is important.
If you are putting variables into query make sure that the quotes start and properly, .(dot) is used to concatenate so end the string , use .(dot) put variable again use .(dot) , start the string.
"string".$variable."string continues.."
hope it helps..
I understand this has been discussed before but since this post in late 2010 and other discussions around that time when issues were raised - Does FILTER_VALIDATE_EMAIL make a string safe for insertion in database? - I have tried some of the situations described, such as using single quotes and the ` characters in an email form where I am using FILTER_VALIDATE_EMAIL and it has blocked them from being entered into the database.
Have recent releases of PHP fixed earlier issues and is it safe?
I'm tempted to also use mysql_real_escape_string(), presumably the two functions can be used in parallel without any conflict?
Here is the mailing list code that I am using to put addresses into the database
<?php
// connects the database access information this file
include("mailing_list_include.php");
// the following code relates to mailing list signups only
if (($_POST) && ($_POST["action"] == "unsub")) {
// trying to ubsubscribe; validate email addresses
if ($_POST["email"] == "") {
header("Location: mailing_list_remove.php");
exit;
} else {
// connect to database
doDB();
// filtering out anything that isn't an email address
if ( filter_var(($_POST["email"]), FILTER_VALIDATE_EMAIL) == TRUE) {
echo '';
} else {
echo 'Invalid Email Address';
exit;
}
// check that email is in the database
emailChecker($_POST["email"]);
// get number of results and do action
if (mysqli_num_rows($check_res) < 1) {
// free result
mysqli_free_result($check_res);
// print failure message
$display_block = "We couldn't find ".$_POST["email"].". No action has therefore been taken.";
} else {
// get value of ID from result
while ($row = mysqli_fetch_array($check_res)) {
$id = $row["id"];
}
// unsubscribe the address
$del_sql = "DELETE FROM subscribers
WHERE id = '".$id."'";
$del_res = mysqli_query($mysqli, $del_sql)
or die(mysql_error($mysqli));
$display_block = " Your email address, ".$_POST["email"].", is unsubscribed!";
}
mysqli_close($mysqli);
}
}
?>
<html>
<?php echo "$display_block";?>
</html>
The filter_var flag FILTER_VALIDATE_EMAIL will do what it says = Validate value as e-mail, meaning if its not an email it will return false.
You might be looking for FILTER_SANITIZE_EMAIL which will (Remove all characters, except letters, digits and !#$%&'*+-/=?^_`{|}~#.[] )
or
FILTER_SANITIZE_STRING will Strip tags, optionally strip or encode special characters.
Tho I don't recommend w3schools it has a list of filter_var flags http://www.w3schools.com/php/php_ref_filter.asp
Also as others have said, use PDO's prepared query's tobe safe, you can find a great pdo example here: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html#10 which will explain a few things and there is also a simple pdo CRUD (Create Retrieve Update Delete) class here: http://www.phpro.org/classes/PDO-CRUD.html
good luck...
Although the item is successfully added to the database, I'm not sure that I'm executing the mysql_real_escape_string() function correctly and, thus, getting the error. Any help is appreciated.
Success!
Warning: array_map() [function.array-map]: Argument #2 should be an array in /home/site4/public_html/lab/mailing_list_dev_1-0/mailing_list_add.php on line 32
Thanks for signing up!
Here's the code in question...
<?php
// connects the database access information this file
include("mailing_list_include.php");
// the following code relates to mailing list signups only
if (($_POST) && ($_POST["action"] == "sub")) {
if ($_POST["email"] == "") {
header("Location: mailing_list_add.php");
exit;
} else {
// connect to database
doDB();
// filtering out anything that isn't an email address
if ( filter_var(($_POST["email"]), FILTER_VALIDATE_EMAIL) == TRUE) {
echo 'Success!';
} else {
echo 'Invalid Email Address';
exit;
}
// check that the email is in the database
emailChecker($_POST["email"]);
// get number of results and do action
if (mysqli_num_rows($check_res) < 1) {
// free result
mysqli_free_result($check_res);
// cleans all input variables at once
$email = array_map("mysqli_real_escape_string", ($_POST["email"]));
// add record
$add_sql = "INSERT INTO subscribers (email)
VALUES('".$_POST["email"]."')";
$add_res = mysqli_query($mysqli, $add_sql)
or die(mysqli_error($mysqli));
$display_block = "<p>Thanks for signing up!</p>";
// close connection to mysql
mysqli_close($mysqli);
} else {
// print failure message
$display_block = "You're email address, ".$_POST["email"].", is already subscribed.";
}
}
}
?>
<html>
<?php echo "$display_block";?>
</html>
You're treating $_POST['email'] as an array, which it probably ins't.
If you only intended to escape email, do
$email = mysqli_real_escape_string($dbConn, $_POST['email']);
Then in your INSERT statement, use the escaped $email instead of $_POST['email']
$add_sql = "INSERT INTO subscribers (email) VALUES('$email')";
array_map() is meant for arrays. If all you have is a single value then just call the function directly.
There is at least one bug, here:
// Does not work because $_POST["email"] is a string, not an array
$email = array_map("mysqli_real_escape_string", ($_POST["email"]));
This looks like something you adapted from code that was working, but right now it's broken. You probably wanted something like this:
$post = array_map("mysqli_real_escape_string", $_POST["email"]);
after which you can use $post["email"] safely, as it has been escaped.
Of course escaping everything inside $_POST is possibly not the best way to go about this. There's still the mundane but spot-on way to consider:
$email = mysqli_real_escape_string($_POST['email']);
This is apparently not mysqli_real_escape_string problem but array_map() problem. Or rather misuse of the latter one.
However, you will face mysqli_real_escape_string() problem as soon as you solves this one.
To solve this latter your doDB() function have to return connection id, which you have to use with every mysqli_* function.
$conn = doDB();
$email = mysqli_real_escape_string($conn,$_POST["email"]);
thus you will have all your [listed] problems solved but I believe that emailChecker will may cause the same kind of problem of inexistent $check_res variable. Instea d of which such a function apparently have to return just a boolean and used like
if (!emailChecker($_POST["email"])) {
I was wondering how do I allow only one email address? Also how can I only check for the # sign in the email address to validate the email?
Here is my PHP code.
if (isset($_GET['email']) && strlen($_GET['email']) <= 255) {
$email = mysqli_real_escape_string($mysqli, strip_tags($_GET['email']));
} else if($_GET['email'] && strlen($_GET['email']) >= 256) {
echo '<p>Your email cannot exceed 255 characters!</p>';
}
Don't.
Use a completely RFC-compliant validator instead, followed up with an actual mail to the address. Truly, sending a mail to the address is the only real way to make sure it's a legitimate email address.
PHP has filter_var which can be used like this:
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
if (strpos($email, "#") === true) {
// VALID
}
}
This is a simple way to check if common address are valid (and will not allow obvious fakes) however, this doesn't make sure your email address is valid according to the RFC 822, RFC 2822, or RFC 3696.
I would also like to point this out. That will validate an email address according to the proper RFCs.
If this is a form, you can use input type="email" in your form. It is part of HTML5, so it isn't implemented in all browsers yet.
This won't serve the full purpose, but it will prevent a single page load for obvious mistakes (forgetting # or .com) to help a little. Browsers which implement it prevent you from submitting the form if it's invalid; also, Apple devices will utilize a special keyboard for that entry with "#" and ".com" present.
(Just an extra piece of info, since I don't know your whole situation.)
how do I allow only one email address?
Run SELECT query to see if there is such an email already.
how can I only check for the # sign in the email
strpos would be enough.
Though it would be a good idea to confirm email address by sending a letter to that address, you know.
Also you have a few things to correct in your code.
your else if statement is not necessary, there should be just else
and mysqli_real_escape_string shouldn't be in the validation section. It is database related function, not validation one.
And if it's registration form, it should use POST method
so, smth like this
$err = array();
if (empty($_POST['email']) $err['email'] = "email cannot be empty";
if (strlen($_POST['email']) >= 256) $err['email'] = "email is too long";
if (!strpos("#",$_POST['email'])) $err['email'] = "malformed email";
$query = "SELECT 1 FROM members WHERE email ='".
mysqli_real_escape_string($mysqli, $_POST['email'])."'";
$res = mysqli_query($mysqli, $query) or trigger_error(mysqli_error($mysqli).$query);
if (mysqli_num_rows($res)) $err['email']="email already present";
//other validations as well
if (!$err) {
//escape all the data.
//run your insert query.
header("Location: ".$_SERVER['REQUEST_URI']);
exit;
} else {
foreach($_POST as $key => $value) {
$_FORM[$key]=htmlspecialchars($value,ENT_QUOTES);
}
include 'form.php';
}
try using regex expression for it... you can find patterns in google
on eg:
if (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email)){
echo "<center>Invalid email</center>";
}else{
echo "<center>Valid Email</center>";}
}
Edited for preg_match:
if (!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i", $email)){
echo "<center>Invalid email</center>";
}else{
echo "<center>Valid Email</center>";
}