有没有一种方法可以测试一个区间,而不需要重复编写代码:
if ($int>$min && $int<$max)
像一个函数:
function testRange($int,$min,$max){
return ($min<$int && $int<$max);
}
使用方法:
if (testRange($int,$min,$max))
PHP 有这样的内置函数吗?或者有其他方法可以实现吗?
用1000000次循环测试了你的3种方法。
t1_test1: ($val >= $min && $val <= $max)
: 0.3823毫秒
t2_test2: (in_array($val, range($min, $max))
: 9.3301毫秒
t3_test3: (max(min($var, $max), $min) == $val)
: 0.7272毫秒
T1最快,基本上就是这个:
function t1($val, $min, $max) {
return ($val >= $min && $val <= $max);
}
function t1($val, $min, $max) {
if ($val >= $min && $val <= $max) {return true;} else {return false;}
}
- Pathrostrue
或 false
,不需要编写其他代码。 - SBH我认为没有比你的函数更好的方法。
它清晰易懂,容易理解,并返回条件的结果(没有复杂的return (...) ? true : false
)。
虽然没有内置函数,但你可以通过适当地调用min()
和max()
函数来轻松实现。
// Limit integer between 1 and 100000
$var = max(min($var, 100000), 1);
大多数给定的例子都假设测试范围[$a..$b],$a <= $b,即范围的极端值是按低到高的顺序排列的,并且大多数假设所有值都是整数。
但我需要一个函数来测试$n$是否在$a$和$b$之间,如此处所述:
Check if $n is between $a and $b even if:
$a < $b
$a > $b
$a = $b
All numbers can be real, not only integer.
有一种简单的测试方法。
我基于这样一个事实进行测试,即当$n$在$a$和$b$之间时,($n-$a)
和($n-$b)
的符号不同,而当$n$在$a$..$b$范围之外时,它们的符号相同。
此函数适用于测试递增、递减、正数和负数,而不仅限于测试整数。
function between($n, $a, $b)
{
return (($a==$n)&&($b==$n))? true : ($n-$a)*($n-$b)<0;
}
我无法发表评论(声望不够),所以在此修改Luis Rosety的回答:
function between($n, $a, $b) {
return ($n-$a)*($n-$b) <= 0;
}
in_array()
和range()
来完成此操作。if (in_array($value, range($min, $max))) {
// Value is in range
}
注意 然而,正如评论中所指出的那样,如果你关注性能,这并不是一个好的解决方案。生成一个数组(特别是在较大的范围内)会减慢执行速度。
除此之外,还有一个叫做filter_var()
的本地函数可以检查范围。它不能返回完全符合要求的值(永远不会返回true),但我们可以通过“欺骗”的方式进行更改。
我认为这不是一段好的代码,因为可读性不够好,但我展示它作为一种可能性:
return (filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]]) !== false)
$someNumber
、$min
和$max
,使用该过滤器的filter_var
函数将在数字超出范围时返回布尔值false,而在范围内时返回数字本身。表达式(!== false
)使函数在数字在范围内时返回true。!=
,则在范围为-5;+5内的数字0会返回false(而应返回true)。如果使用类型转换((bool)
)也会发生同样的情况。// EXAMPLE OF WRONG USE, GIVES WRONG RESULTS WITH "0"
(bool)filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]])
if (filter_var($someNumber, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]])) ...
想象一下(来自其他回答):
if(in_array($userScore, range(-5, 5))) echo 'your score is correct'; else echo 'incorrect, enter again';
$userScore = ''
),这是正确的,因为in_array
在这里被设置为默认的非严格模式,这意味着范围也会创建0
,而'' == 0
(非严格模式),但'' !== 0
(如果您使用严格模式)。很容易错过这样的事情,这就是为什么我写了一点关于这个的原因。我学到的是严格运算符是默认的,程序员只能在特殊情况下使用非严格运算符。我认为这是一个好的教训。这里的大多数例子都会在某些情况下失败,因为没有使用严格检查。
尽管如此,我喜欢filter_var,您可以使用上面(或下面,如果我已经“上升”)的函数并创建自己的回调函数,将其用作FILTER_CALLBACK
过滤器。您可以返回布尔值,甚至添加openRange
参数。另一个好处是,您可以使用其他函数,例如检查数组或POST/GET值的每个数字的范围。这是一个非常强大的工具。
使用比较运算符比调用任何函数都要快得多。我不确定这是否存在,但我认为它不存在。
这是对@Mark Paspirgilis提供的答案进行扩展,允许可选择的包含并返回布尔响应。
public function between($p_value, $p_min, $p_max, $p_inclusive=0) {
## 0 = all inclusive; -1 = left inclusive; 1 = right inclusive
if ($p_inclusive == -1) {
return (bool)($p_value >= $p_min && $p_value < $p_max);
}
else if ($p_inclusive == 1) {
return (bool)($p_value > $p_min && $p_value <= $p_max);
}
else {
return (bool)($p_value >= $p_min && $p_value <= $p_max);
}
} # END FUNCTION between
一种可能性(不是解决方案):
$mysqli->query("SELECT $value BETWEEN $min and $max as test")->fetch_object()->test;
$value
、$min
和 $max
的类型。如果其中一个可以是任意字符串(最坏的情况是来自用户),那么这就是 SQL 注入风险,您将会被黑客攻击。 - Matmarbon
in_array()
和range()
的可怕方法外,我认为没有其他方法。 - Pekkaif($int between $min and $max)
的语言结构会很好,但我担心我见过唯一实现这个功能的语言是SQL。 - Wes P