鲜为人知的 PHP range() 函数
作为一个 PHPer ,如果想要你生成 [1,31]
区间的 31 个数字,你一般会怎么做?
仔细想想,好好回忆一下,你第一时间想到的,会不会是使用一个 for
循环来生成,就像下面这样
$days = array(); for($i = 1; $i <= 31; $i++ ) { $days[] = $i; }
我想,应该,很少人会使用 range()
函数来生成
$days = range(1,31,1);
我不知道这是不是我们 PHPer 的悲剧,因为,似乎,很少有教程会交代可以使用 foreach(range())
的方式来代替 for
循环。
其实,PHP 中的 range()
函数比 Python 中的 range()
强大多了,除了没有使用生成器的方式。
range() 函数
根据官方文档,range()
函数被归纳为 「 数组函数 」,因为它的结果就是产生一个数组,一个普通数组。
range()
函数的原型如下
array range ( mixed $start , mixed $end [, number $step = 1 ] )
range()
函数根据范围 [$start,$end]
创建一个数组,步长为 $step
,默认步长为 1
注意: 返回的区间是一个左闭右闭的区间,也就是包含了 $start 和 $end 两个值。
参数 | 说明 |
---|---|
start | 返回的数组区间序列的第一个值 |
end | 返回的数组区间序列结束于 end 的值 |
step | 如果设置了步长 step,会被作为单元之间的步进值。step 应该为 正值。不设置 step 则默认为 1。 |
用法一 : $start 和 $end 参数都是整数
-
返回整数区间 [0,12] 且步长为 1 的数组
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) foreach (range(0, 12) as $number) { echo $number; }
-
返回整数区间 [0,100] 且步长为 10 的数组
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100) foreach (range(0, 100, 10) as $number) { echo $number; }
-
返回整数区间 [0,99] 且步长为 10 的数组
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90) foreach (range(0, 99, 10) as $number) { echo $number, " " ; }
注意:返回的数组的最后一个值为 90 ,因为 100 < 99 ,所以不满足条件
-
如果步长为负数,那么会取该步长的绝对值
// array(0, 2, 4, 6, 8, 10, 12) foreach (range(0, 12,2) as $number) { echo $number; }
-
如果 $start < $end,那么返回的数组会从大到小
// array(12, 10, 8, 6, 4, 2, 0) foreach (range(12, 0,2) as $number) { echo $number; }
-
如果步长 $step 为
0
,会抛出一个异常// Warning: range(): step exceeds the specified range var_dump(range(12, 0, 0));
-
如果步长为字符串,那么会使用
intval()
转换为整数,如果转换后的结果为0
,则参考6
// array(12, 10, 8, 6, 4, 2, 0) foreach (range(12, 0,'2a') as $number) { echo $number; }
用法二 : $start 和 $end 参数可以是整数也可以是浮点数,$step 也可以是浮点数
-
$start 和 $end 是浮点数,而 $step 是整数,结果和整数是类似的
// array(12.8, 10.8, 8.8, 6.8, 4.8, 2.8) foreach (range(12.8, 2.2,2) as $number) { echo $number; }
-
$start 和 $end 是浮点数,且 $step 也是浮点数,结果和整数也是类似的
// array(12.8, 10.3, 7.8, 5.3, 2.8) foreach (range(12.8, 2.2,2.5) as $number) { echo $number; }
-
如果步长为字符串,那么会使用
doubleval()
转换为浮点数,如果步长为0.0
那么将抛出异常// array(12.8, 10.3, 7.8, 5.3, 2.8) foreach (range(12.8, 2.2,'2.5') as $number) { echo $number; }
转换后步长为 0 则抛出异常
// Warning: range(): step exceeds the specified range foreach (range(12.8, 2.2,'a2.5') as $number) { echo $number; }
用法三 : $start 和 $end 如果有一个是整数或者浮点数
$start 和 $end 如果有一个是整数或者浮点数,而另一个是字符串,那么会将另一个也转换为整数或者浮点数
-
一个是整数而另一个是字符串整数,那么会将另一个转换为整数,结果和都是整数是类似的
// array(0, 2, 4, 6, 8, 10, 12) foreach (range(0, '12',2) as $number) { echo $number; }
-
一个是浮点数而另一个是字符串整数或浮点数,那么会将另一个转换为浮点数,结果和都是整数是类似的
// array(12.8, 10.8, 8.8, 6.8, 4.8, 2.8) foreach (range(12.8, '2', 2) as $number) { echo $number; }
用法四 : $start 和 $end 如果全部是字符串
$start 和 $end 如果全部是字符串,那么会取两个字符串的第一个字母,并按照 ASCII 字母顺序表,取步长对应的值
-
如果 $start 和 $end 都是单个字母,那么直接按照 ASCII 顺序取步长的值
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); foreach (range('a', 'i') as $letter) { echo $letter; }
-
如果按照 ASCII 顺序,$start 大于 $end ,那么会反向步长取值,这个和整数是类似的
// array('c', 'b', 'a'); foreach (range('c', 'a') as $letter) { echo $letter; }
-
如果 $start 或 $end 任意一个字符串长度大于 1 ,那么只会取第一个字母
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); foreach (range('abc', 'i') as $letter) { echo $letter; }
-
如果两个都是字符串,而其中一个是整数字符串或者浮点数字符串,那也会当作普通字符串来处理
echo implode("",range("9 ","Q")); //space after the 9 // prints 9:;<=>?@ABCDEFGHIJKLMNOPQ