Editing form to sanitize/validate phone number
Asked Answered
M

3

13

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);
Multiform answered 12/4, 2013 at 18:45 Comment(1)
See this previous article: #3091362, and this one for various formats: #124059Display
H
24

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.

Hove answered 12/4, 2013 at 18:53 Comment(6)
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.Multiform
@Multiform 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.Hove
You should probably allow () as well : preg_replace("|(?mi-Us)[^0-9 \\-\\(\\)\\+\\/]|", '', $_REQUEST['phone'])Tannate
@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.Hove
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.Tannate
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.Tannate
V
14

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.

Viperous answered 12/4, 2013 at 19:0 Comment(0)
C
0

You could try using preg_replace to filter out any non-numeric characters, then you can check the length of whats remaining to see if its a phone number (should be either 7,9 or maybe 10 digits)

// remove anything thats not a number from the string
function only_numbers($number) { return preg_replace('/[^0-9]/', '', $number) };
// test that the string is only 9 numbers long
function isPhone($number) { return strlen(only_numbers($number)) == 9; }

Just make sure to use the only_numbers value when using the value after validating it.

-Ken

Cardigan answered 12/4, 2013 at 18:52 Comment(1)
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.Tannate

© 2022 - 2024 — McMap. All rights reserved.