What's the difference between "filter_var" and "preg_replace" in PHP?

I have numbers coming out of the database (very controlled input) that will have underscores before and after them. They are saved as follows:

_51_ _356_

      

They won't be saved in any other format, but there will be times when I only need to get numbers from them. I decided to use either

$x = filter_var($myNumber, FILTER_SANITIZE_NUMBER_INT);

      

or

$y = preg_replace("/[^0-9]/","",$myNumber);

      

I'm not sure about the nuances between the two in the backend, but they both give exactly what I need (I think so, one way or another), so it doesn't matter to me what I use. What are the pros and cons of using each of these options? (For example, is it okay to use an array or some other weird thing I might need to know about? One is using too many resources?)

+3


source to share


3 answers


Well, in your case, there isn't much difference. More preg_replace

expensive in the resource, I think, since it had to parse the regex pattern.

Alternatively, you can use trim :



echo trim('_12_', '_');

      

It will remove the '_' on both sides, I think this is the most readable way.

+2


source


Filters don't use regular expressions, but work in a similar way: iterating over a char -by- char string and removing characters that don't match the pattern:

for (i = 0; i < Z_STRLEN_P(value); i++) {
    if ((*map)[str[i]]) {
        buf[c] = str[i];
        ++c;
    }
}

      

@ http://lxr.php.net/xref/PHP_5_6/ext/filter/sanitizing_filters.c#filter_map_apply

a is FILTER_SANITIZE_NUMBER_INT

defined as [^0-9+-]

:

/* strip everything [^0-9+-] */
const unsigned char allowed_list[] = "+-" DIGIT;
filter_map     map;

filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
filter_map_apply(value, &map);

      



@ http://lxr.php.net/xref/PHP_5_6/ext/filter/sanitizing_filters.c#php_filter_number_int

Of course, [^0-9+-]

this is not a valid expression for filtering integers, so be prepared for the unexpected:

$x = filter_var("+++123---", FILTER_SANITIZE_NUMBER_INT);
var_dump($x); // WTF?

      

My suggestion is to stick with regular expressions: they are explicit and much less buggy than filters.

+2


source


I wanted to try several different methods for this, so set up the following test. It looks like for your case, trim is by far the best option, since it should only look at the beginning and end of the line instead of each character. Here are my test results for 10,000,000 random integers surrounded by underscores running PHP 7.0.18.

preg_replace: 1.9469740390778 seconds.

filter_var: 1.6922700405121 seconds.

str_replace: 0.72129797935486 seconds.

trim: 0.37275195121765 seconds.

And here is my code in case anyone wants to run tests like this:

<?php
$ints = array();//array_fill(0, 10000000, '_1029384756_');
for($i = 0; $i < 10000000; $i++) {
$ints[] = '_'.mt_rand().'_';
}

$start = microtime(true);
foreach($ints as $v) {
preg_replace('/[^0-9]/', '', $v);
}
$end = microtime(true);
echo 'preg_replace in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
filter_var($v, FILTER_SANITIZE_NUMBER_INT);
}
$end = microtime(true);
echo 'filter_var in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
str_replace('_', '', $v);
}
$end = microtime(true);
echo 'str_replace in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
trim($v, '_');
}
$end = microtime(true);
echo 'trim in '.($end-$start).' seconds.',PHP_EOL;

      

+1


source







All Articles