How to check if an integer is within a range of numbers in PHP?
Asked Answered
P

16

106

How can I check if a given number is within a range of numbers?

Pouf answered 13/1, 2011 at 18:55 Comment(1)
Related: How to check if integer is between a range?Misusage
T
181

The expression:

($min <= $value) && ($value <= $max)

will be true if $value is between $min and $max, inclusively

See the PHP docs for more on comparison operators

Tiffinytiffy answered 13/1, 2011 at 18:58 Comment(9)
No it won't. Both comparison operators should be <=, or the operands of the second part of the expression should be swapped. ($value should not be greater than $max).Helldiver
You must have added that comment while I was correcting my error... this expression is now correctTiffinytiffy
Depending on whether the OP really means "integer" when asking for "integer" this will produce false results when $value is a float. Also, since the comparison is loose, passing a string might produce false result, e.g. (0 <= 'string') && ('string' <= 10) ); is true due to type juggling.Colis
@Gordon, only if you wish the boundary values to be treated inclusively... but a valid point, nonethelessTiffinytiffy
While it's true that the PHP interpreter does not require the parentheses, it's a matter of style as to whether it is helpful to engineers. Personally, I like the explicit nature of the parentheses in this expression and I don't think they add clutter. However, I think that they would start to feel noisy if you include the (int) casts. In that instance, I would probably elect to leave them out.Tiffinytiffy
there is no provided helper function in PHP to check if a number between 2 numbers?Kidskin
I'd recommend dropping the parenthesis but using and instead of && because and has much lower precendence (in case the code is later changed a lot).Gumshoe
Certainly approach, but personally, I think knowledge of order of precedence should not be relied upon to make an expression understandable on first reading. It's necessary for definitively resolving an expression, but for human readers, I think that's too high and cognitive demandTiffinytiffy
It's really missing a Python-like syntax: $min <= $value <= $maxBarranquilla
C
135

You can use filter_var

filter_var(
    $yourInteger, 
    FILTER_VALIDATE_INT, 
    array(
        'options' => array(
            'min_range' => $min, 
            'max_range' => $max
        )
    )
);

This will also allow you to specify whether you want to allow octal and hex notation of integers. Note that the function is type-safe. 5.5 is not an integer but a float and will not validate.

Detailed tutorial about filtering data with PHP:

Colis answered 13/1, 2011 at 18:59 Comment(0)
C
53

Might help:

if ( in_array(2, range(1,7)) ) {
    echo 'Number 2 is in range 1-7';
}

http://php.net/manual/en/function.range.php

Copulate answered 28/1, 2017 at 13:37 Comment(5)
Worth noting that has a memory cost due to the generation of the range.Tiffinytiffy
@pr1nc3 but this solution is very slow and very memory hungry when it's a large range.Portuna
Agreed, this is way less elegant than the accepted solution and it will take much longer to execute on larger arrays because you have to perform a search on the array to find the value. It's faster, less memory hungry, and just as few lines to use the accepted solution.Mebane
Does not handle float valuesLignite
As others commented, it seems range() will allocate all the items in the range to then compare just with the boundaries. If the range is big, this is a very bad solution in terms of memory use.Guardado
I
23

You could whip up a little helper function to do this:

/**
 * Determines if $number is between $min and $max
 *
 * @param  integer  $number     The number to test
 * @param  integer  $min        The minimum value in the range
 * @param  integer  $max        The maximum value in the range
 * @param  boolean  $inclusive  Whether the range should be inclusive or not
 * @return boolean              Whether the number was in the range
 */
function in_range($number, $min, $max, $inclusive = FALSE)
{
    if (is_int($number) && is_int($min) && is_int($max))
    {
        return $inclusive
            ? ($number >= $min && $number <= $max)
            : ($number > $min && $number < $max) ;
    }

    return FALSE;
}

And you would use it like so:

var_dump(in_range(5, 0, 10));        // TRUE
var_dump(in_range(1, 0, 1));         // FALSE
var_dump(in_range(1, 0, 1, TRUE));   // TRUE
var_dump(in_range(11, 0, 10, TRUE)); // FALSE

// etc...
Islean answered 8/2, 2016 at 14:59 Comment(0)
H
12
if (($num >= $lower_boundary) && ($num <= $upper_boundary)) {

You may want to adjust the comparison operators if you want the boundary values not to be valid.

Handicraft answered 13/1, 2011 at 18:58 Comment(0)
M
7

You can try the following one-statement:

if (($x-$min)*($x-$max) < 0)

or:

if (max(min($x, $max), $min) == $x)
Misusage answered 12/3, 2015 at 18:39 Comment(1)
min() and max() will use comparision in the actual hardware implementation so doing both min and max and single comparision will result in always doing three in total. Instead, simply writing if ($min < $x and $x < $max) which will do two comparisions in worst case and only one if the value $x is smaller than $min limit. The variant with multiplication might be faster with assembler because it can use CPU pipelining very effectively but in case of PHP, I'd recommend testing that instead of assuming it's better than two compariosions with shortcut and in between.Gumshoe
D
7

Some other possibilities:

if (in_array($value, range($min, $max), true)) {
    echo "You can be sure that $min <= $value <= $max";
}

Or:

if ($value === min(max($value, $min), $max)) {
    echo "You can be sure that $min <= $value <= $max";
}

Actually this is what is use to cast a value which is out of the range to the closest end of it.

$value = min(max($value, $min), $max);

Example

/**
 * This is un-sanitized user input.
 */
$posts_per_page = 999;

/**
 * Sanitize $posts_per_page.
 */
$posts_per_page = min(max($posts_per_page, 5), 30);

/**
 * Use.
 */
var_dump($posts_per_page); // Output: int(30)
Disaccustom answered 22/11, 2016 at 14:17 Comment(0)
P
1

using a switch case

    switch ($num){

        case ($num>= $value1 && $num<= $value2): 
            echo "within range 1";
        break;
        case ($num>= $value3 && $num<= $value4): 
            echo "within range 2";
        break;
        .
        .
        .
        .
        .

        default: //default
            echo "within no range";
        break;
     }
Premium answered 9/9, 2012 at 18:33 Comment(1)
Should be switch(true), otherwise if $num == 0, the case logic fails because PHP tries to match 0 == ($num>= $value1 && $num<= $value2), etc. I've suggested this as an edit.Galvanoscope
B
1

I've created a simple helper function.

if ( !function_exists('number_between') )
{
    /**
     * number_between
     * 
     * @param {integer} $number
     * @param {array} $range [min, max]
     * @return {boolean}
     */
    function number_between(
            int $number, 
            array $range
    ){
        
        if(
                count($range) !== 2 || 
                is_numeric($range[0]) === FALSE || 
                is_numeric($range[1]) === FALSE
        ){
            throw new \Exception("number_between second parameter must contain two numbers.", E_WARNING);
        }
        
        if( 
                in_array($number, range($range[0], $range[1]))
        ){
            return TRUE;
        }else{
            return FALSE;
        }
    }
    
}
Blanco answered 16/7, 2022 at 14:44 Comment(0)
B
0

Another way to do this with simple if/else range. For ex:

$watermarkSize = 0;

if (($originalImageWidth >= 0) && ($originalImageWidth <= 640)) {
    $watermarkSize = 10;
} else if (($originalImageWidth >= 641) && ($originalImageWidth <= 1024)) {
    $watermarkSize = 25;
} else if (($originalImageWidth >= 1025) && ($originalImageWidth <= 2048)) {
    $watermarkSize = 50;
} else if (($originalImageWidth >= 2049) && ($originalImageWidth <= 4096)) {
    $watermarkSize = 100;
} else {
    $watermarkSize = 200;
}
Broderick answered 3/5, 2016 at 23:47 Comment(0)
C
0

I created a function to check if times in an array overlap somehow:

    /**
     * Function to check if there are overlapping times in an array of \DateTime objects.
     *
     * @param $ranges
     *
     * @return \DateTime[]|bool
     */
    public function timesOverlap($ranges) {
        foreach ($ranges as $k1 => $t1) {
            foreach ($ranges as $k2 => $t2) {
                if ($k1 != $k2) {
                    /* @var \DateTime[] $t1 */
                    /* @var \DateTime[] $t2 */
                    $a = $t1[0]->getTimestamp();
                    $b = $t1[1]->getTimestamp();
                    $c = $t2[0]->getTimestamp();
                    $d = $t2[1]->getTimestamp();

                    if (($c >= $a && $c <= $b) || $d >= $a && $d <= $b) {
                        return true;
                    }
                }
            }
        }

        return false;
    }
Coaxial answered 31/3, 2018 at 20:58 Comment(0)
P
0

Here is my little contribution:

function inRange($number) {
  $ranges = [0, 13, 17, 24, 34, 44, 54, 65, 200];
  $n = count($ranges);

  while($n--){
    if( $number > $ranges[$n] )
      return $ranges[$n]+1 .'-'. $ranges[$n + 1];
  }
Panarabism answered 24/10, 2019 at 8:39 Comment(0)
R
0
$ranges = [
    1 => [
        'min_range' => 0.01,
        'max_range' => 199.99
    ],
    2 => [
        'min_range' => 200.00,
    ],
];

foreach($ranges as $value => $range){
    if(filter_var($cartTotal, FILTER_VALIDATE_FLOAT, ['options' => $range])){
        return $value;
    }
}
Rinderpest answered 23/11, 2020 at 15:34 Comment(1)
Can someone explain why this is wrong (minus)?Pilate
C
-1
function limit_range($num, $min, $max)
{
  // Now limit it
  return $num>$max?$max:$num<$min?$min:$num;
}

$min = 0;  // Minimum number can be
$max = 4;  // Maximum number can be
$num = 10;  // Your number
// Number returned is limited to be minimum 0 and maximum 4
echo limit_range($num, $min, $max); // return 4
$num = 2;
echo limit_range($num, $min, $max); // return 2
$num = -1;
echo limit_range($num, $min, $max); // return 0
Chassidychassin answered 13/3, 2014 at 11:19 Comment(0)
C
-1

I have function for my case

Use:

echo checkRangeNumber(0);
echo checkRangeNumber(1);
echo checkRangeNumber(499);
echo checkRangeNumber(500);
echo checkRangeNumber(501);
echo checkRangeNumber(3001);
echo checkRangeNumber(999);

//return

0
1-500
1-500
1-500
501-1000
3000-3500
501-1000

function checkRangeNumber($number, $per_page = 500)
{
    //$per_page = 500; // it's fixed number, but... 

    if ($number == 0) {
        return "0";
    }

    $num_page = ceil($number / $per_page); // returns 65
    $low_limit = ($num_page - 1) * $per_page + 1; // returns 32000
    $up_limit = $num_page * $per_page; // returns 40
    return  "$low_limit-$up_limit";
}
Charming answered 25/6, 2021 at 11:55 Comment(0)
A
-3

Thank you so much and I got my answer by adding a break in the foreach loop and now it is working fine.

Here are the updated answer:

foreach ($this->crud->getDataAll('shipping_charges') as $ship) {
  if ($weight >= $ship->low && $weight <= $ship->high) {
      $val = $ship->amount;
      break;
      }
      else
      {
        $val = 900;
      }
     }
     echo $val ;
Allysonalma answered 9/3, 2021 at 20:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.