1

I need to validate an input from text area. It is complex and i'm unable to figure out how i can do it best? Can you guys help?

Input from the text area are basically host names or ips. The input can be of any of the following formats:

x.x.x.x (single IP)
x.x.x.x-x.x.x.x (range of IPs)
x.x.x.x/x.x.x.x (IP and mask)
x.x.x.x/xx (IP and CIDR)
URL (with or without http:// and https:// prefixes)
domain name in format: xxxxxxx.xxx

Also multiple values can be given, like: 192.168.1.1 192.168.1.2/192.168.1.4

I am able to get the lines of textbox using the following code:

$text = trim($targets);
$textAr = explode("\n", $text);
$textAr = array_filter($textAr, 'trim');

foreach ($textAr as $line) {


} 

I am unable to proceed further. Please help.

Thanks, Dave

3
  • 4
    Use filter_var Commented Aug 2, 2013 at 9:48
  • 1
    You can also use this great lib github.com/Respect/Validation Commented Aug 2, 2013 at 9:50
  • @sash Why did you remove my answer. I was just trying to help Commented Sep 20, 2013 at 12:25

1 Answer 1

2

If you don't mind being slightly loose on your validation, you can do something simple such as this:

function filter_fn($input)
{
    $input = trim($input);
    $regex_ip = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/';
    $regex_range = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})-([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/';
    $regex_cidr = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2})$/';
    $regex_sub = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/';

    if (filter_var($input, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => $regex_ip)))) {
        return $input;
    }

    if (preg_match($regex_range, $input)) {
        return $input;
    }

    if (preg_match($regex_cidr, $input)) {
         return $input;
    }

    if (preg_match($regex_sub, $input)) {
        return $input;
    }

    if (filter_var($input, FILTER_VALIDATE_URL)) {
        return $input;
    }

    if (filter_var('http://'.$input, FILTER_VALIDATE_URL)) {
        return $input;
    }

    return false;
}

$textAr = explode("\n", $text);
$textAr = array_filter($textAr, 'trim');
foreach ($textAr as $line) {
    $success = filter_var($line, FILTER_CALLBACK, array('options' => 'filter_fn'));
    if (!$success) {
        // It failed.
    } else {
        // It worked.
    }
} 

Note that in my example, I used both preg_match and filter_var with FILTER_VALIDATE_REGEXP. Both are identical in this case, so that first filter_var could have just as easily been replaced with:

preg_match($regex_ip, $input)

Or, even:

filter_var($input, FILTER_VALIDATE_IP)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot. When you said, 'if i'm slightly loose on validation', what do you mean? Can you suggest me when this wouldn't work?
You will still need a little more validation if you, for instance, wanted to validate that an ipv4 address is actually valid. e.g. this will pass with 555.555.555.555, so you would need additional constraints for that. It really depends on your use-case whether or not this would work. As it stands now, it is quite basic and would work for simple validation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.