Editing form to sanitize/validate phone number

37,599

Solution 1

Have you looked into PHP's preg_replace function? You can strip out any non-numeric character by using preg_replace('/[^0-9]/', '', $_POST['phone']).

Once you filter out the character data, you can always check to see if it is of a desired length:

$phone = preg_replace('/[^0-9]/', '', $_POST['phone']);
if(strlen($phone) === 10) {
    //Phone is 10 characters in length (###) ###-####
}

You can also use PHP's preg_match function as discussed in this other SO question.

Solution 2

There are a couple of ways to do it... examples:

// If you want to clean the variable so that only + - . and 0-9 can be in it you can:
$number = filter_var($number, FILTER_SANITIZE_NUMBER_INT);

// If you want to clean it up manually you can:
$phone = preg_replace('/[^0-9+-]/', '', $_POST['phone']);

// If you want to check the length of the phone number and that it's valid you can:
if(strlen($_POST['phone']) === 10) {
    if (!preg_match('/^[0-9-+]$/',$var)) { // error } else { // good }
}

Obviously some edits may need to be made dependent on the country and other misc factors.

Share:
37,599
user2275638
Author by

user2275638

Updated on July 09, 2022

Comments

  • user2275638
    user2275638 almost 2 years

    I have very limited experience with PHP and I'm really hoping someone can help me.

    What I want to do is sanitize/validate the phone number input so that only numbers are allowed.

    I think I need to use FILTER_SANITIZE_NUMBER_INT but I'm not sure where or how to use it.

    Here is my code:

    <?php
    
    // Replace the email address with the one that should receive the contact form inquiries.
    define('TO_EMAIL', '########');
    
    $aErrors = array();
    $aResults = array();
    
    /* Functions */
    
    function stripslashes_if_required($sContent) {
    
        if(get_magic_quotes_gpc()) {
            return stripslashes($sContent);
        } else {
            return $sContent;
        }
    }
    
    function get_current_url_path() {
    
        $sPageUrl = "http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
        $count = strlen(basename($sPageUrl));
        $sPagePath = substr($sPageUrl,0, -$count);
        return $sPagePath;
    }
    
    function output($aErrors = array(), $aResults = array()){ // Output JSON
    
        $bFormSent = empty($aErrors) ? true : false;
        $aCombinedData = array(
            'bFormSent' => $bFormSent,
            'aErrors' => $aErrors,
            'aResults' => $aResults
            );
    
        header('Content-type: application/json');
        echo json_encode($aCombinedData);
        exit;
    }
    
    // Check supported version of PHP
    if (version_compare(PHP_VERSION, '5.2.0', '<')) { // PHP 5.2 is required for the safety filters used in this script
    
        $aErrors[] = 'Unsupported PHP version. <br /><em>Minimum requirement is 5.2.<br />Your version is '. PHP_VERSION .'.</em>';
        output($aErrors);
    }
    
    
    if (!empty($_POST)) { // Form posted?
    
        // Get a safe-sanitized version of the posted data
        $sFromEmail = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
        $sFromName = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
    
        $sMessage  = "Name: ".stripslashes_if_required($_POST['name']);
        $sMessage .= "\r\nEmail: ".stripslashes_if_required($_POST['email']);
        $sMessage .= "\r\nBusiness: ".stripslashes_if_required($_POST['business']); 
        $sMessage .= "\r\nAddress: ".stripslashes_if_required($_POST['address']);
        $sMessage .= "\r\nPhone: ".stripslashes_if_required($_POST['phone']);
        $sMessage .= "\r\nMessage: ".stripslashes_if_required($_POST['message']);
        $sMessage .= "\r\n--\r\nEmail sent from ". get_current_url_path();
    
        $sHeaders  = "From: '$sFromName' <$sFromEmail>"."\r\n";
        $sHeaders .= "Reply-To: '$sFromName' <$sFromEmail>";
    
        if (filter_var($sFromEmail, FILTER_VALIDATE_EMAIL)) { // Valid email format?
    
            $bMailSent = mail(TO_EMAIL, "New inquiry from $sFromName", $sMessage, $sHeaders);
            if ($bMailSent) {
                $aResults[] = "Message sent, thank you!";
            } else {
                $aErrors[] = "Message not sent, please try again later.";
            }
    
        } else {
            $aErrors[] = 'Invalid email address.';
        }
    } else { // Nothing posted
        $aErrors[] = 'Empty data submited.';
    }
    
    
    output($aErrors, $aResults);
    
  • user2275638
    user2275638 about 11 years
    I've changed $sMessage .= "\r\nPhone: ".stripslashes_if_required($_POST['phone']); to $sMessage .= "\r\nPhone: ".preg_replace('/[^0-9+-]/', '', $_POST['phone']); . Is this an ok way to do this? It seems to work just fine.
  • Kyle
    Kyle about 11 years
    @user2275638 If your goal is to only allow 0-9 and the +/- symbol, then yes. It will remove everything from $_POST['phone'] that is not a number or the +/- symbol.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    You should probably allow () as well : preg_replace("|(?mi-Us)[^0-9 \\-\\(\\)\\+\\/]|", '', $_REQUEST['phone'])
  • Kyle
    Kyle over 9 years
    @snotwaffle There might be a problem with your expression. When I try it, it just gives me back the original phone number. Also, () should not count when you are determining whether a phone number is 10 characters in length. If I allow (), then the user could enter 12345678() and pass the validation.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    I'm not too hot on regexes, so I'm not sure how to make a regex that forces the parentheses to be at the front, with one or more digits between them (after an optional international dialing code), but that's where they should be/how they should work. Perhaps something from html5pattern.com/Phones will suit your needs.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    You don't need to make a function to check that a string is a number; use PHP's built-in is_numeric(). It works with floats and ints (including signed numbers). However, it allows an 'e'/'E' in floats. filter_var() with a FILTER_SANITIZE_INT parameter would work.
  • Agi Hammerthief
    Agi Hammerthief over 9 years
    Actually, you could pass a repeat of any one of those characters and pass validation. It's more like an allowed characters list. Besides, regexes aren't meant to validate data, only that the data conforms to (a) specific pattern(s). They're not very useful for phone numbers because the only practical/reliable way to know if your form's been given a valid phone number (even if it's in a valid format) is to dial it and find out if somebody/the person you expect answers.