Jump to content

US Phone Number Validation


monkeytooth

Recommended Posts

Alright so I am writing up a function to verify various formats of US based phone numbers.. And I seemed to have run into a snag.

This is what I have gotten so far, and for the most part works well.

function validate_phoneUS($number){
$numStripX = array('(', ')', '-', '.', '+');
$numCheck = str_replace($numStripX, '', $number); 
$firstNum = substr($number, 0, 1);
if(($firstNum == 0) || ($firstNum == 1)) {return false;}
elseif(!is_numeric($numCheck)){return false;}
elseif(strlen($numCheck) > 10){return false;}
elseif(strlen($numCheck) < 10){return false;}
else{
	$formats = array('###-###-####', '(###) ###-####', '(###)###-####', '##########', '###.###.####', '(###) ###.####', '(###)###.####');
	$format = trim(ereg_replace("[0-9]", "#", $number));
	return (in_array($format, $formats)) ? true : false;
}
}

 

When I try to run these test numbers down the line..

$number1 = '0234567890';
$number2 = '1234567890';
$number3 = "(555)555-5555";
$number4 = '555-555-5555';
$number5 = '555.555.5555';
$number6 = '5555555555';
$number7 = "(555) 555-5555";

 

I get these as a result..

 

0234567890 is bad.

1234567890 is bad.

(555)555-5555 is bad.

555-555-5555 is a valid phone number.

555.555.5555 is a valid phone number.

5555555555 is a valid phone number.

(555) 555-5555 is bad.

 

Where I am stuck is on the numbers that have the parenthesis wrapped around them. For a while I had it working with them and coming back as a valid number, and then I changed a couple things else where for something else. and now they come back as bad. I am getting tired, and I need some extra eyes to help me figure this out.. what did I snag myself on?

Link to comment
Share on other sites

Do you want it to store it as just the number? =P

If so, preg_replace all other things with nothing.

Then check if it is a number, but I wouldn't use is_numeric, but rather is greater than and smaller than to check the numbers.

If you want to check it further use some preg_match along with regex.

Link to comment
Share on other sites

It will eventually be stored yes and unfortunately at the will of the client I am doing it for, storing it as its typed by the end user, and its pretty much demanded upon that I have it validate as I am looking to build the function, which is still in the works per say but I want to nip this little piece in the bud before I continue on, rather than move on and keep building up and come back to it later..

Link to comment
Share on other sites

Here is an excerpt from a validation class for one of my old projects.

<?php
class Validation {
public $default_filters = array(
	'email' =>array(
		'regex'=>'/^[^@]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+$/',
		'message'=> 'is not a valid email format'
	),
	'phone' => array(
		'regex'=>'/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/',
		'message' => 'is not a valid US phone number format.'
	),
	'zip' => array(
		'regex'=>'/(^\d{5}$)|(^\d{5}-\d{4}$)/',
		'message'=>'is not a valid US zipcode format.'
	)
);
public $filter_list = array();

function Validation($filters=false) {
	if(is_array($filters)) {
		$this->filters = $filters;
	} else {
		$this->filters = array();
	}
}

function validate($filter,$value) {
	if(in_array($filter,$this->filters)) {
		if(in_array('default_filter',$this->filters[$filter])) {
			$f = $this->default_filters[$this->filters[$filter]['default_filter']];
			if(in_array('message',$this->filters[$filter])) {
				$f['message'] = $this->filters[$filter]['message'];
			}
		} else {
			$f = $this->filters[$filter];
		}
	} else {
		$f = $this->default_filters[$filter];
	}
	if(!preg_match($f['regex'],$value)) {
		$ret = array();
		$ret[$filter] = $f['message'];
		return $ret;
	}
	return true;
}
}
?>

 

You can use it like this:

 

<?php
$validation = new Validation();
echo nl2br(print_r($validation->validate('phone','555-555-1212'),true));
echo nl2br(print_r($validation->validate('phone','(555)-555-1212'),true));
echo nl2br(print_r($validation->validate('phone','555 555 1212'),true));
?>

 

It doesn't match something like 555.555.1212 though.

Link to comment
Share on other sites

$phonenumber='(555)555-5555';

Do you want to limit the length?

Then you can first run a str_len on it, to make sure it's not freaking long. (too long for the db).

 

for example:

if(str_len($phonenumber)<16){

 

}

 

then we want to check if it's a 10 digit long number.

 

$phonenumber='(555)555-5555';

if(strlen($phonenumber)<16){

  if($temppn=preg_replace('/[\(\)-\.]/','',$phonenumber)){

    if(strlen($temppn)==10){

      echo $temppn.' - '.$phonenumber;

    }

  }

}

 

I echoed it, but instead, you enter $phonenumber into the db.

 

You probably want to check if it is a number though. (almost forgot)

 

$phonenumber='(555)555-5555';

if(strlen($phonenumber)<16){

  if($temppn=preg_replace('/[\(\)-\.]/','',$phonenumber)){

    if(strlen($temppn)==10){

      if($temppn>999999999 && $temppn<10000000000){

        echo $temppn.' - '.$phonenumber;

      }

    }

  }

}

Link to comment
Share on other sites

tomfmason that looks like it can work nicely thank you. Curious, I am not to great with regex, so I wouldn't know how to edit it well enough to allow for phone numbers typed like xxx.xxx.xxx or (xxx)xxx.xxxx, is it possible to edit it in a way to do that or is that an idea that would break it?

Link to comment
Share on other sites

tomfmason that looks like it can work nicely thank you. Curious, I am not to great with regex, so I wouldn't know how to edit it well enough to allow for phone numbers typed like xxx.xxx.xxx or (xxx)xxx.xxxx, is it possible to edit it in a way to do that or is that an idea that would break it?

 

Actually that was pretty easy to add

'/^\(?(\d{3})\)?[-\. ]?(\d{3})[-\. ]?(\d{4})$/'

 

If you replace the phone filter's regex with that one it should match the following as well

 

<?php
echo nl2br(print_r($validation->validate('phone','555.555.1212'),true));
echo nl2br(print_r($validation->validate('phone','(555).555.1212'),true));
echo nl2br(print_r($validation->validate('phone','(555)555.1212'),true));
?>

Link to comment
Share on other sites

lol, I'm not really good at regex. I actually did a wrong in my regex. Should be '/[\(\)\-\.]/'. Should escape the -

 

A program I liked very much for testing regex is regex buddy. It isn't really written for php though, but setting it for perl usually does it for me, and you can test stuff against text.

Link to comment
Share on other sites

It is important to note that if the string matches the given validation a boolean is returned(true) and if it doesn't match an array is returned like this:

<?php
$validation = new Validation();
echo nl2br(print_r($validation->validate('phone','(555)---555.1212'),true));
?>

 

would return

Array
(
[phone] => is not a valid US phone number format.
)

 

You can also use this for zip codes(XXXXX or XXXXX-XXXX etc) and email addresses.

Link to comment
Share on other sites

tomfmason that looks like it can work nicely thank you. Curious, I am not to great with regex, so I wouldn't know how to edit it well enough to allow for phone numbers typed like xxx.xxx.xxx or (xxx)xxx.xxxx, is it possible to edit it in a way to do that or is that an idea that would break it?

i think (off the top of my head)

preg_match('/^\(?\d{3}\)?[\.\- ]?\d{3}[\.\- ]\d{4}$/',$phone):

should capture:

(xxx) xxx-xxxx

(xxx)-xxx-xxxx

xxx.xxx.xxxx

xxxxxxxxxx

or any combination thereof

 

Link to comment
Share on other sites

tomfmason that looks like it can work nicely thank you. Curious, I am not to great with regex, so I wouldn't know how to edit it well enough to allow for phone numbers typed like xxx.xxx.xxx or (xxx)xxx.xxxx, is it possible to edit it in a way to do that or is that an idea that would break it?

i think (off the top of my head)

preg_match('/^\(?\d{3}\)?[\.\- ]?\d{3}[\.\- ]\d{4}$/',$phone):

should capture:

(xxx) xxx-xxxx

(xxx)-xxx-xxxx

xxx.xxx.xxxx

xxxxxxxxxx

or any combination thereof

 

 

that is pretty much exactly what I posted except you don't have to escape the - e.g.

 

'/^\(?(\d{3})\)?[-\. ]?(\d{3})[-\. ]?(\d{4})$/'

 

 

Link to comment
Share on other sites

I think I am going to end up going one of these routes, however I am still curious about my original code.. anyone able to tell me why the numbers with ( and ) are failing? is it something to do specifically with ( or ) in the strings or? is there something else somewhere I might have missed with that. Its just gonna eat at my curiosity until i figure it out, and I can foresee myself trying to play with it until it does work, one of those "blinders on" mentalities..

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.