← PHP array_rand() 函数:从数组中随机抽取键名的实用教程 没有下一篇了 →

PHP range()函数:快速生成区间数组的实战教程

著
原创 2026-10-08 PHP 已有人查阅

一、range()解决的是什么问题

写代码时经常需要一串连续的值:生成1到100的编号、构造a到z的字母表、按10为间隔取刻度点。这些需求如果都用for循环手动push,代码会又长又容易出错。range()把这个过程压缩成一次函数调用,直接返回一个排好序的数组。

它的定位是生成器,不是遍历工具。拿到数组之后你可以print_r、foreach、array_map,也可以直接当参数传给别的函数。

二、函数原型与参数

range(string|int|float $start, string|int|float $end, int|float $step = 1): array
参数 说明 是否必需
start 区间起始值 必需
end 区间结束值 必需
step 步长,默认为1 可选

返回值:一个包含区间内所有元素的数组,元素类型与起止值保持一致。

三个参数都支持int、float和单字符string。step为正数时从start递增到end,step为负数时从start递减到end。step不能为0,传0会触发E_WARNING并返回false。

三、数字区间的生成

最基础的用法:

<?php
$numbers = range(1, 5);
print_r($numbers);

输出:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)

起点和终点都包含在结果里,这是range()与很多语言里左闭右开区间不同的地方。写分页、生成序号时要注意这个"两端都算"的特性。

指定步长:

<?php
foreach (range(0, 100, 10) as $number) {
    echo $number . ", ";
}

输出:

0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,

步长为10时,序列按10递增。如果终点不能被步长整除,比如range(0,95,10),之后一个元素是90,不会为了凑到95而多出一个元素。这一点和"取到不超过终点的较大值"一致。

四、字母区间的生成

range()对单字符的处理比较特别,它会按ASCII顺序推进:

<?php
$alphabet = range('a', 'g');
print_r($alphabet);

输出:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
    [6] => g
)

反向也支持:

<?php
$array = range('z', 'u');
print_r($array);

输出:

Array
(
    [0] => z
    [1] => y
    [2] => x
    [3] => w
    [4] => v
    [5] => u
)

起点大于终点时,range()会自动按递减方向生成,不需要把step写成负数。这一点比手写for循环省事。

五、几个容易踩坑的地方

坑一:字母序列只能单字符。传range('a','z')没问题,传range('aa','ad')结果不符合直觉。PHP对多字符字符串的处理是按字符串比较规则来的,不会把它当成"字母表扩展"。需要多字符序列时,得自己用循环拼。

坑二:浮点步长的精度。range(0,1,0.1)这类调用,由于浮点数本身无法精确表示0.1,生成的元素可能带上很长的尾数。项目里如果需要精确的小数刻度,建议先生成整数再用除法换算,比如range(0,10)后每个元素除以10。

坑三:step为0。传0会报警告并返回false,后续foreach会报错。调用前应确认step不为0。

坑四:大区间吃内存。range(1,10000000)会一次性生成一千万个元素的数组,内存直接顶上去。PHP里没有惰性求值的range,需要处理大区间时改用for循环或生成器函数逐个产出。

个人经验:曾经在一个报表导出功能里用range(1,500000)构造行号,本地测试没问题,上线后遇到大数据量直接把内存打满。后来改成在循环里用$i自增,内存占用立刻降下来。range()适合小规模区间,大规模区间还是循环更稳妥。

六、项目实例

实例一:代码号学习编程·生成分页页码

<?php
$totalPages = 8;
$pages = range(1, $totalPages);

foreach ($pages as $page) {
    echo "<a href='?page={$page}'>{$page}</a> ";
}

页码是连续的整数序列,range()一行就能拿到,比for循环加push简洁。

实例二:代码号学习编程·构造字母索引

<?php
$letters = range('A', 'F');

foreach ($letters as $letter) {
    echo $letter . " 选项\n";
}

用于生成选择题选项、表格列标等场景。

实例三:代码号学习编程·按步长取刻度

<?php
$scale = range(0, 50, 5);
print_r($scale);

输出:

Array
(
    [0] => 0
    [1] => 5
    [2] => 10
    [3] => 15
    [4] => 20
    [5] => 25
    [6] => 30
    [7] => 35
    [8] => 40
    [9] => 45
    [10] => 50
)

适合图表刻度、时间间隔等场景。

七、range()与for循环的取舍

对比项 range() for循环
代码长度 一行 需要初始化、条件、自增
内存占用 一次性生成整个数组 逐个处理,占用低
适用规模 小到中等区间 任意规模
可读性 表达"区间"语义清晰 表达"迭代"更直接

选择原则:区间不大、需要把结果当数组用时,用range();区间很大、只需要逐个处理时,用for循环或生成器。不要为了少写几行代码,把一个几百万元素的区间塞进数组。

八、本节课程知识要点

  1. range()返回包含起点和终点的数组,两端都算。

  2. step控制递增或递减幅度,默认为1,传0会警告并返回false。

  3. 起点大于终点时自动按递减方向生成,不必手写负步长。

  4. 字母区间只对单字符有效,多字符字符串的行为不符合直觉。

  5. 浮点步长存在精度问题,精确小数刻度建议先整数后换算。

  6. 大区间会占用较多内存,规模大时改用for循环或生成器。

九、常见问题

问:range(5,1)会报错吗?

不会。会自动生成5、4、3、2、1的递减序列。

问:range()生成的数组键名是怎样的?

从0开始的连续整数键,与元素值无关。

问:能不能用range()生成日期序列?

不能直接生成。需要先生成时间戳或天数区间,再用date()换算成日期。比如range(0,6)配合strtotime生成最近七天的日期。

问:step可以是小数吗?

可以,但要注意浮点精度。0.1、0.2这类值在二进制下无法精确表示,结果可能带尾差。

← PHP array_rand() 函数:从数组中随机抽取键名的实用教程 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号