Strip e-mail addresses from a string in PHP - php

I operate an archive of e-mail for a law firm that receives mail from Postfix and uses a PHP script to insert messages into a database. This works mostly fine but sometimes the regular expression I use to parse e-mail addresses from the From, To, and Cc headers does not capture e-mail addresses with 100% accuracy. I have tried the other solutions posited here on stackoverflow (using filter_var(), using imap_rfc822_parse_adrlist, using the regex in question 1028553) with actually less success than what I have.
I am looking to minimize system calls (I use way too many pregs right now) and increase accuracy. The current function takes an input of header text (the From, To, or Cc fields) and returns "clean" e-mail addresses stripped of brackets, quotes, comments, etc.
Any help anyone can provide would be appreciated, as I am stumped!
Wendy
My function:
function return_proper ($email_string) {
if (is_array($email_string)) {
$x = "";
foreach ($email_string as $val) {
$x .= "$val,";
}
$email_string = substr($x, 0, -1);
}
$email_string = strtolower(preg_replace('/.*?([A-Za-z0-9\_\+\.\'-]+#[A-Za-z0-9\.-]+).*?/', '$1,', $email_string));
$email_string = preg_replace('/\>/', "", $email_string);
$email_string = preg_replace('/,$/', "", $email_string);
$email_string = preg_replace('/^\'/', "", $email_string);
return $email_string;
}

function return_proper($email_string) {
if (is_array($email_string)) {
// Deal with array
foreach ($email_string as $email_string_line) {
$results[] = return_proper($email_string_line);
}
$result = implode(',', $results);
} else {
preg_match_all('/[A-Za-z0-9\_\+\.\'-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]+/', $email_string, $matches);
$result = implode(',', $matches[0]);
}
return strtolower($result);
}

Related

how to partially mask/hide email address using PHP

Im trying to achieve the following with PHP
sample#gmail.com => s*****#gmail.com
sa#yahoo.com => **#yahoo.com
sampleaddress#hotmail.com => samplead*****#hotmail.com
I want to hide last five characters in the portion that stays before '#'
I can write long code to do this by splitting and then replacing based on lengths, but Im sure there must be an easy way to do this using PHP functions, any help please?
UPDATE:
Im adding my code here, Im sure its not efficient, and thats the reason Im asking it here
$email = 'sampleuser#gmail.com';
$star_string = '';
$expl_set = explode('#',$email);
if(strlen ($expl_set[0]) > 5){$no_stars = 5; }else{$no_stars = strlen ($expl_set[0]); }
for($i=0;$i<$no_stars; $i++)
{
$star_string.='*';
}
$masked_email = substr($expl_set[0], 0, -5).$star_string.'#'.$expl_set[1];
You can wrap it into a function, making it easier to call multiple times.
Basically, split the address and the domain, replace $mask number of characters in the end of the string (default 5) with *, or the length of the address if it's shorter than the amount of masked characters.
function mask_email($email, $masks = 5) {
$array = explode("#", $email);
$string_length = strlen($array[0]);
if ($string_length < $masks)
$masks = $string_length;
$result = substr($array[0], 0, -$masks) . str_repeat('*', $masks);
return $result."#".$array[1];
}
The above would be used like this
echo mask_email("test#test.com")."\n";
echo mask_email("longeremail#test.com");
which would ouput this
****#test.com
longer*****#test.com
You can also specify the number you want filtered by using the second parameter, which is optional.
echo mask_email("longeremail#test.com", 2); // Output: longerema**#test.com
Live demo

PHP - Not give result when do many processing task

I'm working on mining tweets using some text processing (with PHP) like removing html tags, mention / username, link, non-alphanumeric, repeating syllable n character, noise word
When I get search results and directly perform all processing mentioned above, my app does not give resulti. The app just can show results when do processing on
removing tag html, mentions, links, nonalphanum, n repeating character (not all textprocessing steps).
I want to ask why that in problems come, is PHP code has specific criteria in the process?
In PHP, is it possible to define order time text to be longer processing ? (so I can use all my process step)
Any help will be greatly appreciated. Thanks
I add all preprocessing line of codes. hope you can analyze if there any problem guys. Thanks
function addspaces($value){
return " ".$value." "; }
function containsTLD($string) {
preg_match(
"/(AC($|\/)|\.AD($|\/)|\.AE($|\/)|\.AERO($|\/)|\.AF($|\/)|\.AG($|\/)|\.AI($|\/)|\.AL($|\/)|\.AM($|\/)|\.AN($|\/)|\.AO($|\/)|\.AQ($|\/)|\.AR($|\/)|\.ARPA($|\/)|\.AS($|\/)|\.ASIA($|\/)|\.AT($|\/)|\.AU($|\/)|\.AW($|\/)|\.AX($|\/)|\.AZ($|\/)|\.BA($|\/)|\.BB($|\/)|\.BD($|\/)|\.BE($|\/)|\.BF($|\/)|\.BG($|\/)|\.BH($|\/)|\.BI($|\/)|\.BIZ($|\/)|\.BJ($|\/)|\.BM($|\/)|\.BN($|\/)|\.BO($|\/)|\.BR($|\/)|\.BS($|\/)|\.BT($|\/)|\.BV($|\/)|\.BW($|\/)|\.BY($|\/)|\.BZ($|\/)|\.CA($|\/)|\.CAT($|\/)|\.CC($|\/)|\.CD($|\/)|\.CF($|\/)|\.CG($|\/)|\.CH($|\/)|\.CI($|\/)|\.CK($|\/)|\.CL($|\/)|\.CM($|\/)|\.CN($|\/)|\.CO($|\/)|\.COM($|\/)|\.COOP($|\/)|\.CR($|\/)|\.CU($|\/)|\.CV($|\/)|\.CX($|\/)|\.CY($|\/)|\.CZ($|\/)|\.DE($|\/)|\.DJ($|\/)|\.DK($|\/)|\.DM($|\/)|\.DO($|\/)|\.DZ($|\/)|\.EC($|\/)|\.EDU($|\/)|\.EE($|\/)|\.EG($|\/)|\.ER($|\/)|\.ES($|\/)|\.ET($|\/)|\.EU($|\/)|\.FI($|\/)|\.FJ($|\/)|\.FK($|\/)|\.FM($|\/)|\.FO($|\/)|\.FR($|\/)|\.GA($|\/)|\.GB($|\/)|\.GD($|\/)|\.GE($|\/)|\.GF($|\/)|\.GG($|\/)|\.GH($|\/)|\.GI($|\/)|\.GL($|\/)|\.GM($|\/)|\.GN($|\/)|\.GOV($|\/)|\.GP($|\/)|\.GQ($|\/)|\.GR($|\/)|\.GS($|\/)|\.GT($|\/)|\.GU($|\/)|\.GW($|\/)|\.GY($|\/)|\.HK($|\/)|\.HM($|\/)|\.HN($|\/)|\.HR($|\/)|\.HT($|\/)|\.HU($|\/)|\.ID($|\/)|\.IE($|\/)|\.IL($|\/)|\.IM($|\/)|\.IN($|\/)|\.INFO($|\/)|\.INT($|\/)|\.IO($|\/)|\.IQ($|\/)|\.IR($|\/)|\.IS($|\/)|\.IT($|\/)|\.JE($|\/)|\.JM($|\/)|\.JO($|\/)|\.JOBS($|\/)|\.JP($|\/)|\.KE($|\/)|\.KG($|\/)|\.KH($|\/)|\.KI($|\/)|\.KM($|\/)|\.KN($|\/)|\.KP($|\/)|\.KR($|\/)|\.KW($|\/)|\.KY($|\/)|\.KZ($|\/)|\.LA($|\/)|\.LB($|\/)|\.LC($|\/)|\.LI($|\/)|\.LK($|\/)|\.LR($|\/)|\.LS($|\/)|\.LT($|\/)|\.LU($|\/)|\.LV($|\/)|\.LY($|\/)|\.MA($|\/)|\.MC($|\/)|\.MD($|\/)|\.ME($|\/)|\.MG($|\/)|\.MH($|\/)|\.MIL($|\/)|\.MK($|\/)|\.ML($|\/)|\.MM($|\/)|\.MN($|\/)|\.MO($|\/)|\.MOBI($|\/)|\.MP($|\/)|\.MQ($|\/)|\.MR($|\/)|\.MS($|\/)|\.MT($|\/)|\.MU($|\/)|\.MUSEUM($|\/)|\.MV($|\/)|\.MW($|\/)|\.MX($|\/)|\.MY($|\/)|\.MZ($|\/)|\.NA($|\/)|\.NAME($|\/)|\.NC($|\/)|\.NE($|\/)|\.NET($|\/)|\.NF($|\/)|\.NG($|\/)|\.NI($|\/)|\.NL($|\/)|\.NO($|\/)|\.NP($|\/)|\.NR($|\/)|\.NU($|\/)|\.NZ($|\/)|\.OM($|\/)|\.ORG($|\/)|\.PA($|\/)|\.PE($|\/)|\.PF($|\/)|\.PG($|\/)|\.PH($|\/)|\.PK($|\/)|\.PL($|\/)|\.PM($|\/)|\.PN($|\/)|\.PR($|\/)|\.PRO($|\/)|\.PS($|\/)|\.PT($|\/)|\.PW($|\/)|\.PY($|\/)|\.QA($|\/)|\.RE($|\/)|\.RO($|\/)|\.RS($|\/)|\.RU($|\/)|\.RW($|\/)|\.SA($|\/)|\.SB($|\/)|\.SC($|\/)|\.SD($|\/)|\.SE($|\/)|\.SG($|\/)|\.SH($|\/)|\.SI($|\/)|\.SJ($|\/)|\.SK($|\/)|\.SL($|\/)|\.SM($|\/)|\.SN($|\/)|\.SO($|\/)|\.SR($|\/)|\.ST($|\/)|\.SU($|\/)|\.SV($|\/)|\.SY($|\/)|\.SZ($|\/)|\.TC($|\/)|\.TD($|\/)|\.TEL($|\/)|\.TF($|\/)|\.TG($|\/)|\.TH($|\/)|\.TJ($|\/)|\.TK($|\/)|\.TL($|\/)|\.TM($|\/)|\.TN($|\/)|\.TO($|\/)|\.TP($|\/)|\.TR($|\/)|\.TRAVEL($|\/)|\.TT($|\/)|\.TV($|\/)|\.TW($|\/)|\.TZ($|\/)|\.UA($|\/)|\.UG($|\/)|\.UK($|\/)|\.US($|\/)|\.UY($|\/)|\.UZ($|\/)|\.VA($|\/)|\.VC($|\/)|\.VE($|\/)|\.VG($|\/)|\.VI($|\/)|\.VN($|\/)|\.VU($|\/)|\.WF($|\/)|\.WS($|\/)|\.XN--0ZWM56D($|\/)|\.XN--11B5BS3A9AJ6G($|\/)|\.XN--80AKHBYKNJ4F($|\/)|\.XN--9T4B11YI5A($|\/)|\.XN--DEBA0AD($|\/)|\.XN--G6W251D($|\/)|\.XN--HGBK6AJ7F53BBA($|\/)|\.XN--HLCJ6AYA9ESC7A($|\/)|\.XN--JXALPDLP($|\/)|\.XN--KGBECHTV($|\/)|\.XN--ZCKZAH($|\/)|\.YE($|\/)|\.YT($|\/)|\.YU($|\/)|\.ZA($|\/)|\.ZM($|\/)|\.ZW)/i",
$string,
$M);
$has_tld = (count($M) > 0) ? true : false;
return $has_tld;
}
function cleaner($url) {
$U = explode(' ',$url);
$W =array();
foreach ($U as $k => $u) {
if (stristr($u,".")) {
if (containsTLD($u) === true) {
unset($U[$k]);
return cleaner( implode(' ',$U));
}
}
}
return implode(' ',$U);
}
$regexmention = "/(?<=^|(?<=[^a-zA-Z0-9-_\.]))#([A-Za-z-_\.]+[A-Za-z0-9]+)/i";
$reject = strtolower(implode(" ",file("file.txt")));//bikin deretan kata yg direject, mis: smartfren ga iya gue gw
$rejectarray = array_map('addspaces',explode(" ", $reject) );
$removehtmltag=strip_tags($tweet,"");
$removemention=strtolower(preg_replace($regexmention, "",$removehtmltag));
$removeurl=cleaner($removemention);
$removenonalfa = preg_replace("/[^A-Za-z0-9 ]/", " ",$removeurl );
$removerepeatchar = preg_replace("/(.)\\1+/", "$1", $removerepeatchar);
$removedigit = preg_replace('/\d/', " ", preg_replace("/(.)\\1+/", "$1", $removerepeatchar));
$removerepeatword = implode(' ',array_unique(preg_split('/[\s?:;,.]+/', $removedigit, -1, PREG_SPLIT_NO_EMPTY)));
$removedoublesyllable=preg_replace("/(.*)(\\1+)/", "", $removerepeatword ); //wkwk hahaha
$removeminimumthreechar = preg_replace("/\b\w{1,3}\b/", " ", $removedoublesyllable);
$removenoiseword = addspaces( $removeminimumthreechar ); // " saya ... bb "
$final=trim( str_replace($rejectarray, " ",$removenoiseword) );
//say
echo $final;
It seems that you are passing the maximum time allowed by the web server
Try to use set_time_limit
set_time_limit(0);
Or using too much memory, in this case modify php.ini memory_limit to something reasonable for your case like
memory_limit = 128M

Avoiding 500 line limit exceeded error while sending emails

I am using the PHPMailer library integrated in Joomla for an email component in Joomla. It does work quite well, however I am having an issue with users running the script with 1and1 mail servers. They can get errors like that:
2012-06-14 18:20:34 u65913791 1x1et0-1RocCH2xzU-00qzkq EE transaction error after sending of mail text: msmtp.kundenserver.de[172.19.35.7] 500 Line limit exceeded
Another example from a different user:
SMTP error from remote mail server after end of data:
host mx00.1and1.co.uk [212.227.15.134]: 500 Line limit exceeded
The line limit is not about how many lines but how many characters are actually used in a single line which 1and1 limits to 10240 characters (support answer) - which is actually 10 times more than required in RFC 2822.
I assume the issue is caused by using "wrong" line seperators when the emails is submitted so that the whole email reaches the email server as a single line. I guess that I need to make sure to insert line breaks in my script as PHPMailer fails do so.
Currently I am just receiving the HTML content from a WYSIWYG-editor and put into the PHPMailer object:
// snip, $mail2send is the JMail instance, which inherits PHPMailer
$mail2send->setSubject($mail->subject);
$mail2send->IsHTML(true);
$mail2send->setBody($mail->body);
// snip
How can I insert the appropiate line breaks?
Use chunk_split. This function was designed for tasks like yours and even its default (split at 76 chars) says so.
So your code will be
$mail2send->setSubject($mail->subject);
$mail2send->IsHTML(true);
$mail2send->setBody(chunk_split($mail->body));
Convert to a content transfer encoding such as base64 or quoted-printable, both of which have been devised for encapsulating free-form data. QP is more efficient for predominantly US-ASCII data with the occasional 8-bit character and/or overlong lines.
Of course, if your data is HTML and it is otherwise safe for SMTP, merely adding line terminators where you otherwise have whitespace is a slightly brittle workaround (are you sure you don't have a line-initial "From" anywhere, etc?)
After further investigation the error could be identified: after several replies in an email thread an embedded HTML message had no lines break anymore. I guess an email client involved in the conversation did this.
To overcome this problem I do a HTML-tag-safe wrapping using the following function:
/* HTML-tag-safe wordwrap
* from http://php.net/manual/de/function.wordwrap.php
* by nbenitezl[arroba]gmail[dot]com
*/
function htmlwrap(&$str, $maxLength=76, $char="\r\n"){
$count = 0;
$newStr = '';
$openTag = false;
$lenstr = strlen($str);
for($i=0; $i<$lenstr; $i++){
$newStr .= $str{$i};
if($str{$i} == '<'){
$openTag = true;
continue;
}
if(($openTag) && ($str{$i} == '>')){
$openTag = false;
continue;
}
if(!$openTag){
if($str{$i} == ' '){
if ($count == 0) {
$newStr = substr($newStr,0, -1);
continue;
} else {
$lastspace = $count + 1;
}
}
$count++;
if($count==$maxLength){
if ($str{$i+1} != ' ' && $lastspace && ($lastspace < $count)) {
$tmp = ($count - $lastspace)* -1;
$newStr = substr($newStr,0, $tmp) . $char . substr($newStr,$tmp);
$count = $tmp * -1;
} else {
$newStr .= $char;
$count = 0;
}
$lastspace = 0;
}
}
}
return $newStr;
}

Mirc control codes to html, through php

I realize this has been asked before, on this very forum no less, but the proposed solution was not reliable for me.
I have been working on this for a week or more by now, and I stayed up 'till 3am yesterday working on it... But I digress, let me get to the issue at hand:
For those unaware, mirc uses ascii control codes to control character color, underline, weight, and italics. The ascii code for the color is 3, bold 2, underline 1F, italic 1D, and reverse(white text on black background), 16.
As an example of the form this data is going to come in, we have(in regex because those characters will not print):
\x034this text is red\x033this text is green\x03 \x02bold text\x02
\x034,3this text is red with a green background\x03
Et-cetera.
Below are the two functions I have attempted to modify for my own use, but have returned unreliable results. Before I get into that code, to be specific on 'unreliable', sometimes the code would parse, other times there would still be control codes left in the text, and I can't figure out why. Anyway;
function mirc2html($x) {
$c = array("FFF","000","00007F","009000","FF0000","7F0000","9F009F","FF7F00","FFFF00","00F800","00908F","00FFFF","0000FF","FF00FF","7F7F7F","CFD0CF");
$x = preg_replace("/\x02(.*?)((?=\x02)\x02|$)/", "<b>$1</b>", $x);
$x = preg_replace("/\x1F(.*?)((?=\x1F)\x1F|$)/", "<u>$1</u>", $x);
$x = preg_replace("/\x1D(.*?)((?=\x1D)\x1D|$)/", "<i>$1</i>", $x);
$x = preg_replace("/\x03(\d\d?),(\d\d?)(.*?)(?(?=\x03)|$)/e", "'</span><span style=\"color: #'.\$c[$1].'; background-color: #'.\$c[$2].';\">$3</span>'", $x);
$x = preg_replace("/\x03(\d\d?)(.*?)(?(?=\x03)|$)/e", "'</span><span style=\"color: #'.\$c[$1].';\">$2</span>'", $x);
//$x = preg_replace("/(\x0F|\x03)(.*?)/", "<span style=\"color: #000; background-color: #FFF;\">$2</span>", $x);
//$x = preg_replace("/\x16(.*?)/", "<span style=\"color: #FFF; background-color: #000;\">$1</span>", $x);
//$x = preg_replace("/\<\/span\>/","",$x,1);
//$x = preg_replace("/(\<\/span\>){2}/","</span>",$x);
return $x;
}
function color_rep($matches) {
$matches[2] = ltrim($matches[2], "0");
$bindings = array(0=>'white',1=>'black',2=>'blue',3=>'green',4=>'red',5=>'brown',6=>'purple',7=>'orange',8=>'yellow',9=>'lightgreen',10=>'#00908F',
11=>'lightblue',12=>'blue',13=>'pink',14=>'grey',15=>'lightgrey');
$preg = preg_match_all('/(\d\d?),(\d\d?)/',$matches[2], $col_arr);
//print_r($col_arr);
$fg = isset($bindings[$matches[2]]) ? $bindings[$matches[2]] : 'transparent';
if ($preg == 1) {
$fg = $bindings[$col_arr[1][0]];
$bg = $bindings[$col_arr[2][0]];
}
else {
$bg = 'transparent';
}
return '<span style="color: '.$fg.'; background: '.$bg.';">'.$matches[3].'</span>';
}
And, in case it is relevant, where the code is called:
$logln = preg_replace_callback("/(\x03)(\d\d?,\d\d?|\d\d?)(\s?.*?)(?(?=\x03)|$)/","color_rep",$logln);
Sources: First, Second
I've of course also attempted to look at the methods done by various php/ajax based irc clients, and there hasn't been any success there. As to doing this mirc-side, I've looked there as well, and although the results have been more reliable than php, the data sent to the server increases exponentially to the point that the socket times out on upload, so it isn't a viable option.
As always, any help in this matter would be appreciated.
You should divide the problem, for example with a tokenizer. A tokenizer will scan the input string and turn the special parts into named tokens, so the rest of your script can identify them. Usage example:
$mirc = "\x034this text is red\x033this text is green\x03 \x02bold text\x02
\x034,3this text is red with a green background\x03";
$tokenizer = new Tokenizer($mirc);
while(list($token, $data) = $tokenizer->getNext())
{
switch($token)
{
case 'color-fgbg':
printf('<%s:%d,%d>', $token, $data[1], $data[2]);
break;
case 'color-fg':
printf('<%s:%d>', $token, $data[1]);
break;
case 'color-reset':
case 'style-bold';
printf('<%s>', $token);
break;
case 'catch-all':
echo $data[0];
break;
default:
throw new Exception(sprintf('Unknown token <%s>.', $token));
}
}
This does not much yet, but identify the interesting parts and their (sub-) values as the output demonstrates:
<color-fg:4>this text is red<color-fg:3>this text is green<color-reset> <style-bold>bold text<style-bold>
<color-fgbg:4,3>this text is red with a green background<color-reset>
It should be relatively easy for you to modify the loop above and handle the states like opening/closing color and font-variant tags like bold.
The tokenizer itself defines a set of tokens of which is tries to find them one after the other at a certain offset (starting at the beginning of the string). The tokens are defined by regular expressions:
/**
* regular expression based tokenizer,
* first token wins.
*/
class Tokenizer
{
private $subject;
private $offset = 0;
private $tokens = array(
'color-fgbg' => '\x03(\d{1,2}),(\d{1,2})',
'color-fg' => '\x03(\d{1,2})',
'color-reset' => '\x03',
'style-bold' => '\x02',
'catch-all' => '.|\n',
);
public function __construct($subject)
{
$this->subject = (string) $subject;
}
...
As this private array shows, simple regular expressions and they get a name with their key. That's the name used in the switch statement above.
The next() function will look for a token at the current offset, and if found, will advance the offset and return the token incl. all subgroup matches. As offsets are involved, the more detailed $matches array is simplified (offsets removed) as the main routine normally does not need to know about offsets.
The principle is easy here: The first pattern wins. So you need to place the pattern that matches most (in sense of string length) on top to have this working. In your case, the largest one is the token for the foreground and background color, <color-fgbg>.
In case not token can be found, NULL is returned, so here the next() function:
...
/**
* #return array|null
*/
public function getNext()
{
if ($this->offset >= strlen($this->subject))
return NULL;
foreach($this->tokens as $name => $token)
{
if (FALSE === $r = preg_match("~$token~", $this->subject, $matches, PREG_OFFSET_CAPTURE, $this->offset))
throw new RuntimeException('Pattern for token %s failed (regex error).', $name);
if ($r === 0)
continue;
if (!isset($matches[0])) {
var_dump(substr($this->subject, $this->offset));
$c = 1;
}
if ($matches[0][1] !== $this->offset)
continue;
$data = array();
foreach($matches as $match)
{
list($data[]) = $match;
}
$this->offset += strlen($data[0]);
return array($name, $data);
}
return NULL;
}
...
So the tokenization of the string is now encapsulated into the Tokenizer class and the parsing of the token is something you can do your own inside some other part of your application. That should make it more easy for you to change the way of styling (HTML output, CSS based HTML output or something differnt like bbcode or markdown) but also the support of new codes in the future. Also in case something is missing you can more easily fix things because it's either a non-recognized code or something missing with the transformation.
The full example as gist: Tokenizer Example of Mirc Color and Style (bold) Codes.
Related resources:
Very rudimentary, regex based tokenizer routine example
http://www.mirc.com/colors.html
http://en.wikipedia.org/wiki/Control_key

looking to validate US phone number w/ area code

I'm working on a function to validate a US phone number submitted by a user, which can be submitted in any of the popular number formats people usually use. My code so far is as follows:
$number = '123-456-7890';
function validate_telephone_number($number) {
$formats = array(
'###-###-####',
'(###)###-###',
'(###) ###-###',
'##########'
);
$number = trim(preg_replace('[0-9]', '#', $number));
if (in_array($number, $formats)) {
return true;
} else {
return false;
}
}
First off, this code does not seem to be working, and returns false on all submitted numbers. I can't seem to find my error.
Secondly, I'm looking for an easy way to only allow phone numbers from an array of specific allowed area codes. Any ideas?
For your first question:
preg_replace('/[0-9]/', '#', $number)
or '/\d/'
For the second question this may help you:
$areaCode = substr(preg_replace('/[^\d]/', '', $number),0 , 3);
This will give you the first 3 digits in the number by discarding all other characters.
I'm not familiar with the US area codes format so I cannot help you more with this one.
Bonus:
if (in_array($number, $formats)) {
return true;
} else {
return false;
}
is equivalent to
return in_array($number, $formats);
As a matter of fact any statement of the form
if(<expression>){
return true;
}
else{
return false;
}
can be written as return (bool) <expr>;, but in this case in_array will always return a Boolean so (bool) is not needed.
Your code does not check for well formatted but invalid numbers - for example, no area code starts with 0 or 1 in the US, so this could be checked. Also, your formats do not allow for country code inclusion - +15551234567 would be rejected, for example.
If you don't care about the formatting and just want to validate if the digits in the input amount to a valid US phone number, you could use something like this:
$clean_number = preg_replace("/[^0-9]/", '', $number);
$valid = preg_match("/^(\+?1)?[2-9][0-9]{9}$/", $clean_number);
Of course, this will also accept "foo 5555555555 bar" as a valid number - if you want to disallow that, make the preg_replace more restrictive (e.g, remove only brackets, spaces and dashes).
If you prefer to do this without maintaining a lot of code, you an check out this API that validates a US number and provides several formats for the number https://www.mashape.com/parsify/format
Look here for a code project that has a function for validating phone numbers.

Categories