tags:

views:

90

answers:

5

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>';
}
+6  A: 

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.

Charles
If you look at the comments, you will see that it isn't "completely" valid, as the author would like you to believe. See the comments and then: http://simonslick.com/VEAF/
Nick Presta
As also pointed out in the comments, strict RFC adherence is detremental to the real world. `foo@local-but-not-fully-qualified-host` is a deliverable address, but not valid according to the RFCs.
Charles
+3  A: 

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.

Nick Presta
I do wonder how `FILTER_VALIDATE_EMAIL` validates the address. Can anybody find some documentation on what exactly it does?
deceze
I'm pretty sure they used something like this: http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c?view=markupRegex on line 525.
Nick Presta
That's too bad, really. ;(
deceze
A: 

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>";
} 
KoolKabin
Using regex to validate email is a terrible idea, because an email address isn't a regular expression, it's far too complicated for validation without a proper parser. The closest you might find--while still inaccurate/flawed--is going to be incredibly long: http://ex-parrot.com/~pdw/Mail-RFC822-Address.html
Bauer
ereg is deprecated. @Bauer for the real world it's enough.
Col. Shrapnel
@Col. The thing is that you're creating a chicken and egg problem. A simple regex is enough in the real world because nobody is using addresses that use the full spectrum RFC822 allows. Nobody is using addresses that use the full spectrum RFC822 allows because they often don't work in the real world. It's a sad state of affairs and it's already too late, but everybody should try to validate according to RFC822, and not some arbitrary subset of it.
deceze
@deceze but validation itself is not that important. Depends on the goal and most of time we need confirmation while validation is just optional thing
Col. Shrapnel
@Col. Well, if you don't validate at all, that's fine. If you do, validate according to RFC. Don't validate an RFC subset because it's "good enough".
deceze
@Bauer: There are groups of regular expressions that can properly validate an email address according to the RFCs: http://simonslick.com/VEAF/It is still a pretty bad idea. :)
Nick Presta
A: 

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.)

phoffer
A: 

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';
}
Col. Shrapnel