/    Sign up×
Community /Pin to ProfileBookmark

Validation and input cleansing (WIP)

Here’s something I’m working on. Go ahead and critique it to your hearts desire. Any suggestions will be appreciated. (Yes I know it would be faster to just hard code the drop down list stuff instead of using a for loop on a multidimensional array… But I was being lazy =P)

[code=php]<?php
// Validation Class
// Validates and cleans user based input
// Ver 0.1
// Kenneth Ellis Mccall – August 8th 2007
//
// Functions:
// email():
// Validate an email address
//
// variables:
// $email: Email address.
// $level: Values 1, 2, 3 and 4.
// 1 = Simple regex checking. Default. (Fastest) — Need to add valid TLD’s (.com, .net)
// 2 = Checks to make sure the domain is valid and has an MX record. (Fast)
// 3 = Connects to the mail server and checks to if it really exsists. Doesn’t always work. (Slow)
// 4 = Check to see if the user does exist on the server. Doesn’t always work. (Slowest) — Not completed
//
// phone():
// Validate and clean phone number
//
// variables:
// $phone: Phone number.
// $level: Values 1 and 2.
// 1 = Simple check of US phone number – allow for ()’s, -‘s, spaces and .’s. — Regex isn’t 100% complete to what I want.
// 2 = Format to a simple 10 digit number.
//
// list_pre():
// Returns a form list element of name prefixes and also uses the SELECTED command to show the previous choice
//
// variables:
// $pre: Selection
//
// list_suf():
// Returns a form list element of name suffixes and also uses the SELECTED command to show the previous choice
//
// variables:
// $suf: Selection
//
// list_states():
// Returns a form list element of states and also uses the SELECTED command to show the previous choice
//
// variables:
// $state: Selection
//
// check_pre():
// check to make sure prefixes form element doesn’t have any injection.
//
// variables:
// $pre: prefix selection
//
// check_suf():
// check to make sure suffixes form element doesn’t have any injection.
//
// variables:
// $suf: suffix selection
//
// check_state
// check to make sure states form element doesn’t have any injection.
//
// variables:
// $state: state
//
// slash():
// Escapes strings – auto detects magic quotes and which escaping mechanism to use.
// Use stripslashes() to unescape.
//
// variables:
// $str: string
//
// fixword():
// Converts MS Word quotes and dashes to HTML
//
// variables:
// $str: string

class validation
{
var $states = array(‘AL’=>’Alabama’, ‘AK’=>’Alaska’, ‘AZ’=>’Arizona’, ‘AR’=>’Arkansas’, ‘CA’=>’California’, ‘CO’=>’Colorado’, ‘CT’=>’Connecticut’,
‘DE’=>’Delaware’, ‘DC’=>’District Of Columbia’, ‘FL’=>’Florida’, ‘GA’=>’Georgia’, ‘HI’=>’Hawaii’, ‘ID’=>’Idaho’, ‘IL’=>’Illinois’,
‘IN’=>’Indiana’, ‘IA’=>’Iowa’, ‘KS’=>’Kansas’, ‘KY’=>’Kentucky’, ‘LA’=>’Louisiana’, ‘ME’=>’Maine’, ‘MD’=>’Maryland’,
‘MA’=>’Massachusetts’, ‘MI’=>’Michigan’, ‘MN’=>’Minnesota’, ‘MS’=>’Mississippi’, ‘MO’=>’Missouri’, ‘MT’=>’Montana’, ‘NE’=>’Nebraska’,
‘NV’=>’Nevada’, ‘NH’=>’New Hampshire’, ‘NJ’=>’New Jersey’, ‘NM’=>’New Mexico’, ‘NY’=>’New York’, ‘NC’=>’North Carolina’,
‘ND’=>’North Dakota’, ‘OH’=>’Ohio’, ‘OK’=>’Oklahoma’, ‘OR’=>’Oregon’, ‘PA’=>’Pennsylvania’, ‘RI’=>’Rhode Island’, ‘SC’=>’South Carolina’,
‘SD’=>’South Dakota’, ‘TN’=>’Tennessee’, ‘TX’=>’Texas’, ‘UT’=>’Utah’, ‘VT’=>’Vermont’, ‘VA’=>’Virginia’, ‘WA’=>’Washington’,
‘WV’=>’West Virginia’, ‘WI’=>’Wisconsin’, ‘WY’=>’Wyoming’);

var $pre = array(‘Mr.’=>’Mr.’, ‘Mrs.’=>’Mrs.’, ‘Ms.’=>’Ms.’, ‘Miss’=>’Miss’,’Dr.’=>’Dr.’,’Rev.’=>’Rev.’, ‘Prof.’=>’Prof.’);
var $suf = array(‘0’=>’Select a suffix…’, ‘Sr.’=>’Sr.’, ‘Jr.’=>’Jr.’, ‘I’=>’I’, ‘II’=>’II’, ‘III’=>’III’, ‘IV’=>’IV’, ‘V’=>’V’, ‘M.D.’=>’M.D.’,
‘Ph.D.’=>’Ph.D.’, ‘M.A.’=>’M.A.’, ‘M.B.A.’=>’M.B.A’, ‘B.A.’=>’B.A.’, ‘B.S.’=>’B.S.’, ‘Esq.’=>’Esq.’,);

function email($email, $level=1)
{
$regex = “/^[a-z0-9]+([_\.-][a-z0-9]+)*@([a-z0-9]+([.-][a-z0-9]+)*)+\.[a-z]{2,}$/i”;

if(!preg_match($regex, $email))
{
return 0;
}

if($level > 1)
{
list($username,$domain)=split(‘@’,$email);
if(!checkdnsrr($domain,’MX’))
{
return 0;
}
}

if($level > 2)
{
if(!fsockopen($domain,25,$errno,$errstr,30))
{
return 0;
}
}

if($level > 3)
{
// Open a socket to the mailserver (MX), send ‘HELO’ – wait for the output (Test showed a long delay before
// output was seen. Then do ‘MAIL FROM: $email’ – wait for output and check for ‘250 ok’. Last – ‘RCPT TO: $email’ – wait
// for output – check for ‘250 ok’ (good) or ‘550 sorry, no mailbox here by that name. (#5.7.17)’
// The 3 digit code is what we are looking for – 250 is OK, 550 is ERROR. This will not work for on a lot of mail servers.
}
return 1;
}

function phone($phone, $level=1)
{
// Bokeh from WebDeveloper.com’s forums
$digits = preg_replace(‘/[^d]/’, ”, $phone);

if(strlen($digits) < 10 || strlen($digits) > 11)
{
return 0;
}

if($level > 1)
{
if(strlen($digits) == 11)
{
$digits = ltrim($digits, ‘1’);
}
return $digits; // Return cleaned output
}
return 1;
}

function list_pre($pre)
{
foreach($this->pre as $key=>$val)
{
$ret .= ‘<option value=”‘.$key.'”‘;

if($pre == $key)
{
$ret .= ‘ SELECTED’;
}

$ret .= ‘>’.$val.'</option>’;
}
return $ret;
}

function list_suf($suf)
{
foreach($this->suf as $key=>$val)
{
$ret .= ‘<option value=”‘.$key.'”‘;

if($suf == $key)
{
$ret .= ‘ SELECTED’;
}

$ret .= ‘>’.$val.'</option>’;
}
return $ret;
}

function list_states($state)
{
foreach($this->states as $key=>$val)
{
$ret .= ‘<option value=”‘.$key.'”‘;

if($state == $key)
{
$ret .= ‘ SELECTED’;
}

$ret .= ‘>’.$val.'</option>’;
}
return $ret;
}

function check_pre($pre)
{
if(!$this->pre[$pre])
{
return 0;
}
return 1;
}

function check_suf($suf)
{
if(!$this->suf[$suf])
{
return 0;
}
return 1;
}

function check_state($state)
{
if(!$this->states[$state])
{
return 0;
}
return 1;
}

function slash($str)
{
if(get_magic_quotes_gpc())
{
$str = stripslashes($str);
}

if(function_exists(‘mysql_real_escape_string’))
{
return mysql_real_escape_string($str);
}
elseif(function_exists(‘mysql_escape_string’))
{
return mysql_escape_string($str);
}
else
{
return addslashes($str);
}
}

function fixword($str)
{
// http://us.php.net/manual/en/function.utf8-decode.php#60109
$bad = array(“xe2x80x98”, // left single quote
“xe2x80x99”, // right single quote
“xe2x80x9c”, // left double quote
“xe2x80x9d”, // right double quote
“xe2x80x94”, // em dash
“xe2x80xa6” // elipses
);
$good = array(‘&#8216;’,
‘&#8217;’,
‘&#8220;’,
‘&#8221;’,
‘&mdash;’,
‘&#8230;’);

return str_replace($bad, $good, $str);
}
}
?>[/code]

to post a comment
PHP

10 Comments(s)

Copy linkTweet thisAlerts:
@ellisglauthorSep 14.2007 — I've update the phone function of this class:
[code=php]
<?php
// phone():
// Validate and clean phone number
//
// variables:
// $phone: Phone number.
// $level: Values 1, 2 and 3.
// 1 = Simple check of US phone number - allow for ()'s, -'s, spaces and .'s. Default:--- Regex isn't 100% complete to what I want.
// 2 = Check area code
// 3 = Check prefix.
// $country: 2 char country designator. US is default.
// $format: 1 to Format to a number. Default: 0
function phone($phone, $level=1, $country='us', $format=0)
{
// Save the size of the file by pulling the a file for that country
if(file_exsists($country.'.phone.php'))
{
include_once($country.'.phone.php');
}
else
{
return 0;
}

return 1;
}
?>
[/code]


I current only have the US, US territories and Canada setup in the respective files.

us.phone.php
[code=php]
<?php
// Bokeh from WebDeveloper.com's forums -- Convert to a number
$digits = preg_replace('/[^d]/', '', $phone);

if(strlen($digits) < 10 || strlen($digits) > 11)
{
return 0;
}

if($strlen($digits) > 10)
{
if(substr($digits), 0, 1 != '1')
{
return 0;
}
}

// Area code check
if($level > 1)
{
include_once('us.areacode.php');
}

// Prefix check
if($level > 2)
{
include_once('us.prefix.php');
}

// Format to a number
if($format == 1)
{
if(strlen($digits) == 11)
{
$digits = ltrim($digits, '1');
}
return $digits; // Return cleaned output
}
?>
[/code]


us.areacode.php
[code=php]
<?php
if(strlen($digits) > 10)
{
$area = substr($digits,1,3);
}
else
{
$area = substr($digits,0,3);
}

if(!(($area >= 201 && $area <= 210) ||
($area >= 212 && $area <= 219) ||
($area >= 224 && $area <= 225) ||
($area >= 227 && $area <= 229) ||
($area == 231) ||
($area == 234) ||
($area >= 239 && $area <= 240) ||
($area == 242) ||
($area == 246) ||
($area == 248) ||
($area >= 250 && $area <= 254) ||
($area == 256) ||
($area == 260) ||
($area == 262) ||
($area == 264) ||
($area >= 267 && $area <= 270) ||
($area == 276) ||
($area == 278) ||
($area == 281) ||
($area >= 283 && $area <= 284) ||
($area == 289) ||
($area >= 301 && $area <= 321) ||
($area == 323) ||
($area == 325) ||
($area >= 330 && $area <= 331) ||
($area == 334) ||
($area >= 336 && $area <= 337) ||
($area >= 339 && $area <= 341) ||
($area == 345) ||
($area == 347) ||
($area >= 351 && $area <= 352) ||
($area >= 360 && $area <= 361) ||
($area == 369) ||
($area == 380) ||
($area >= 385 && $area <= 386) ||
($area >= 401 && $area <= 419) ||
($area >= 423 && $area <= 425) ||
($area == 430) ||
($area == 432) ||
($area >= 434 && $area <= 435) ||
($area == 438) ||
($area >= 440 && $area <= 443) ||
($area == 445) ||
($area == 450) ||
($area == 456) ||
($area == 464) ||
($area >= 469 && $area <= 470) ||
($area == 473) ||
($area == 475) ||
($area >= 478 && $area <= 480) ||
($area == 484) ||
($area >= 501 && $area <= 510) ||
($area >= 512 && $area <= 520) ||
($area == 530) ||
($area >= 540 && $area <= 541) ||
($area == 551) ||
($area == 557) ||
($area == 559) ||
($area >= 561 && $area <= 564) ||
($area == 567) ||
($area >= 570 && $area <= 571) ||
($area >= 573 && $area <= 575) ||
($area == 580) ||
($area >= 585 && $area <= 586) ||
($area >= 601 && $area <= 610) ||
($area >= 612 && $area <= 620) ||
($area == 623) ||
($area >= 626 && $area <= 628) ||
($area >= 630 && $area <= 631) ||
($area == 636) ||
($area == 641) ||
($area >= 646 && $area <= 647) ||
($area >= 649 && $area <= 651) ||
($area == 657) ||
($area >= 659 && $area <= 662) ||
($area == 664) ||
($area == 667) ||
($area >= 669 && $area <= 671) ||
($area >= 678 && $area <= 679) ||
($area == 682) ||
($area == 684) ||
($area == 689) ||
($area >= 701 && $area <= 709) ||
($area >= 712 && $area <= 720) ||
($area == 724) ||
($area == 727) ||
($area >= 731 && $area <= 732) ||
($area == 734) ||
($area == 737) ||
($area == 740) ||
($area == 747) ||
($area == 752) ||
($area == 754) ||
($area >= 757 && $area <= 758) ||
($area == 760) ||
($area >= 763 && $area <= 765) ||
($area == 767) ||
($area == 770) ||
($area >= 772 && $area <= 775) ||
($area == 778) ||
($area >= 780 && $area <= 781) ||
($area >= 784 7 && $area <= 87) ||
($area >= 800 && $area <= 810) ||
($area >= 812 && $area <= 819) ||
($area == 822) ||
($area == 828) ||
($area >= 830 && $area <= 833) ||
($area == 835) ||
($area >= 843 && $area <= 845) ||
($area >= 847 && $area <= 848) ||
($area == 850) ||
($area >= 855 && $area <= 870) ||
($area == 872) ||
($area >= 876 && $area <= 878) ||
($area >= 880 && $area <= 882) ||
($area == 888) ||
($area >= 901 && $area <= 910) ||
($area >= 912 && $area <= 920) ||
($area == 925) ||
($area == 928) ||
($area == 931) ||
($area >= 935 && $area <= 937) ||
($area >= 939 && $area <= 941) ||
($area == 947) ||
($area == 949) ||
($area >= 951 && $area <= 952) ||
($area == 954) ||
($area == 956) ||
($area == 959) ||
($area >= 970 && $area <= 973) ||
($area == 975) ||
($area >= 978 && $area <= 979) ||
($area == 980) ||
($area >= 984 && $area <= 985) ||
($area == 989)))
{
return 0;
}
?>
[/code]


us.prefix.php
[code=php]
<?php
if(strlen($digits) > 10)
{
$prefix = substr($digits,4,3);
}
else
{
$prefix = substr($digits,3,3);
}

$f = substr($prefix,0,1)
if($f == '0' || $f == '1')
{
return 0;
}

if($prefix == '211' || $prefix == '311' || $prefix == '411' || $prefix == '511' || $prefix == '555' || $prefix == '611' || $prefix == '711' || $prefix == '811' || $prefix == '911')
{
return 0;
}
?>
[/code]


ca.phone.php
[code=php]
<?php
include_once('us.phone.php');
?>
[/code]
Copy linkTweet thisAlerts:
@bokehSep 16.2007 — [code=php]// 2 = Checks to make sure the domain is valid and has an MX record. (Fast)[/code]You can add that to your list of doesn't always work. A domain does not require an MX record for an email to be valid or to receive emails.

The level 3 test is not necessarily a good idea because it will return false if the mail exchanger is under load without there being any real problem with the address. And level 4 test is a minefield because you are not testing that the email address is good but also that the exchanger finds the incoming connection acceptable.
Copy linkTweet thisAlerts:
@ellisglauthorSep 17.2007 — I nuked level 4 all together from the code - just didn't mention it.

I never knew you could get around not having an MX record when you have mail server on that domain. Hmm..
Copy linkTweet thisAlerts:
@bokehSep 17.2007 — RFC2821 Section 5. Address Resolution and Mail Handling

Once an SMTP client lexically identifies a domain to which mail will be delivered for processing (as described in sections 3.6 and 3.7), a DNS lookup MUST be performed to resolve the domain name [22]. The names are expected to be fully-qualified domain names (FQDNs): mechanisms for inferring FQDNs from partial names or local aliases are outside of this specification and, due to a history of problems, are generally discouraged. The lookup first attempts to locate an MX record associated with the name. If a CNAME record is found instead, the resulting name is processed as if it were the initial name. [B]If no MX records are found, but an A RR is found, the A RR is treated as if it was associated with an implicit MX RR, with a preference of 0, pointing to that host.[/B]
Copy linkTweet thisAlerts:
@ellisglauthorSep 18.2007 — Hmmm I'm not much of a DNS guy (give me fricken headache anything beyond MX, A and C)..
Copy linkTweet thisAlerts:
@bokehSep 18.2007 — The only point having an A record and an MX record is if the webserver and mail exchanger are on different IPs.
Copy linkTweet thisAlerts:
@ellisglauthorSep 18.2007 — Anyways - I think I'm going to make a zip code verification part to this. If you put in CA as the state and 75444 as the zipcode - tit would be false since 75444 would be a texas zipcode.
Copy linkTweet thisAlerts:
@ellisglauthorSep 19.2007 — Any other ideas you would like to add people?
Copy linkTweet thisAlerts:
@ellisglauthorOct 24.2007 — Sorry to bump this - just wondering if anyone else had some extra ideas to add to this.
Copy linkTweet thisAlerts:
@ellisglauthorNov 12.2007 — // Change log:

// 0.4 - Nov 12th, 2007

// Added zip_code() fuction

// Added is_number() function

//

// 0.3 - Nov 10th, 2007

// Various parse and logic errors fixed. Doh!

[upl-file uuid=a9240554-21c9-4763-9651-55e38eb4ff3f size=4kB]validation.zip[/upl-file]
×

Success!

Help @ellisgl spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...