PHP range() 函数
前言range()用来生成一个连续序列的数组是 PHP 里少数几个「天生就返回数组」的函数之一。正因为它看着简单很多人在用它的时候带着三个不准确的印象第一以为它只能生成数字。它同样能生成字符序列range(a, z)是常见的写法。但要注意两个边界都是字符串时生成的是字节序列——range(A, z)会顺带把[ \ ] ^ _这几个符号也包进来因为它们正好落在A和z的 ASCII 区间之间。第二以为负的步长能自动得到降序。PHP 8.3.0 起如果区间是递增的起点小于等于终点却给了负步长会直接抛ValueError。而在 PHP 8.2 及以前range()会去「猜」方向结果常常与预期相反。第三以为它像别的语言那样是左闭右开区间。PHP 的range()是闭区间结果里包含终点。本文按官方手册讲清range()的类型推导规则、PHP 8.3 引入的错误与警告、字符序列的坑以及大区间下的内存问题。一、签名与返回类型推导range(string|int|float $start, string|int|float $end, int|float $step 1): array返回的是数组但元素的类型取决于参数类型规则写在手册里条件结果两个边界都是字符串且$step是整数字节序列通常是 ASCII 字符$start、$end、$step中至少有一个是浮点数浮点数序列其余情况整数序列方向由边界决定$start小于等于$end时递增否则递减。步长$step只负责「每两个元素之间差多少」不负责决定方向。?php // 适用于 PHP 8.0echo implode(, , range(0, 5)), PHP_EOL; // 0, 1, 2, 3, 4, 5echo implode(, , range(5, 0)), PHP_EOL; // 5, 4, 3, 2, 1, 0echo implode(, , range(0, 100, 25)), PHP_EOL; // 0, 25, 50, 75, 100echo implode(, , range(c, a)), PHP_EOL; // c, b, a注意最后一个元素手册说明结果数组的最后一个元素要么是$end要么是它的前一个元素取决于步长。range(0, 10, 4)得到[0, 4, 8]——12超了终点所以停在8。二、PHP 8.3 引入的错误与警告PHP 8.3.0 对range()做了一次行为规范化这是使用它时必须知道的分界线情况PHP 8.3.0 起的行为$step为0抛ValueError$start、$end、$step中存在非有限值INF、-INF、NAN抛ValueError$step为负但区间是递增的$start $end抛ValueError$start或$end是空字符串发出E_WARNING空串按0处理$start或$end是多字节的非数字字符串发出E_WARNING一个边界是数字导致另一个字符串边界被隐式转成整数发出E_WARNING$step是浮点但小数部分为 0如2.0视为整数2结果数组是整数两个边界都是字符串一律生成字节序列旧版本里若一边是数字串另一边会被隐式转成整数也就是说range(1, 5, -1)在 PHP 8.2 上是能跑出结果的方向被「猜」成升序在 PHP 8.3 上会直接报错。升级到 PHP 8.3 时这类调用是最典型的兼容性炸弹应该在迁移前全局搜一遍。三、字符序列好看但危险range(a, z)很直观但它生成的其实是字节区间。ASCII 里大写字母、小写字母被若干符号隔开?php // 适用于 PHP 8.0$a range(a, z);$A range(A, Z);$all range(A, z);echo count($a), , count($A), , count($all), PHP_EOL;echo implode(, $all), PHP_EOL;26 26 58ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyzrange(A, z)得到的 58 个元素里中间的[、\、]、^、_、反引号并不是字母。需要「全部字母」时必须分两段再合并?php // 适用于 PHP 8.0$letters array_merge(range(A, Z), range(a, z));echo count($letters), PHP_EOL; // 52四、实战示例1. 用range()生成分页页码窗口?php // 适用于 PHP 8.0declare(strict_types1);/*** 生成当前页附近的页码窗口例如当前第 5 页、总 20 页、窗口 5 → 3,4,5,6,7** return listint*/function pageWindow(int $current, int $total, int $size 5): array{if ($total 1) {return [];}$half intdiv($size, 2);$start max(1, $current - $half);$end min($total, $start $size - 1);// 靠近尾页时向左补齐保证窗口宽度尽量等于 $size$start max(1, $end - $size 1);return range($start, $end); // 闭区间两端都包含}var_dump(pageWindow(1, 20)); // [1, 2, 3, 4, 5]var_dump(pageWindow(10, 20)); // [8, 9, 10, 11, 12]var_dump(pageWindow(20, 20)); // [16, 17, 18, 19, 20]2. 大区间不要用range()range()会一次性构造完整的数组。生成 1000 万个整数就要在内存里放 1000 万个元素如果还要对它们做array_map()中间还会再产生一份数组。需要惰性序列时用生成器generator?php // 适用于 PHP 8.0declare(strict_types1);/*** 与 range($start, $end, $step) 等价的惰性版本内存占用与区间长度无关。** return Generatorint, int*/function intRange(int $start, int $end, int $step 1): Generator{if ($step 0) {throw new ValueError(步长必须是正整数);}if ($start $end) {for ($i $start; $i $end; $i $step) {yield $i;}} else {for ($i $start; $i $end; $i - $step) {yield $i;}}}$sum 0;foreach (intRange(1, 1_000_000) as $n) {$sum $n;}echo $sum, PHP_EOL; // 500000500000这段代码的内存占用是恒定的无论区间多大。需要数组时再iterator_to_array()转换这样「是否真的需要全部元素」就成了一个显式决定。3. 生成时间点时注意浮点误差?php // 适用于 PHP 8.0// 用整数运算生成「每 15 分钟一个时间点」避开浮点累加误差$base strtotime(2024-01-01 00:00:00);$slots array_map(static fn (int $i): string date(Y-m-d H:i, $base $i * 900),range(0, 95) // 一天 96 个 15 分钟时段);echo $slots[0], ... , $slots[95], PHP_EOL;常见坑点❌range(1, 5, -1)想得到降序 —— PHP 8.3.0 起会抛ValueError递增区间配负步长PHP 8.2 及以前方向靠猜结果与预期相反。✅ 方向交给边界决定range(5, 1)就是降序真要用负步长写成range(5, 1, -1)。❌range(1, 10, 0)想「不按步长、逐个取」—— 旧版本里是死循环式的告警PHP 8.3.0 起抛ValueError。✅ 步长恒为正整数需要逐个取就省略第三个参数。❌ 用range(A, z)当「所有字母」—— 会带进[、\、]、^、_、反引号这 6 个非字母字符。✅array_merge(range(A, Z), range(a, z))。❌ 以为range()是左闭右开、不含终点 —— PHP 是闭区间range(1, 3)得到[1, 2, 3]。✅ 想要「从 0 开始的 N 个值」写range(0, $n - 1)用for ($i 0; $i $n; $i)时要记得这里才是开区间。❌ 用range()生成很大的区间再array_map()—— 数组先完整构造出来内存峰值随区间长度线性上升通常直接 OOM。✅ 用for循环或生成器惰性产生确实要数组时才调用iterator_to_array()。❌ 用浮点步长累加并期望精确值 ——range(0, 1, 0.1)的元素受二进制浮点表示影响末位可能不是0.1的精确倍数用来做等值比较会失败。✅ 需要精确小数时用整数运算先乘成整数再除比较用abs($a - $b) 1e-9或先round()。❌ 依赖range()的元素类型 ——range(1, 5, 2.0)在 PHP 8.3.0 起会返回整数数组浮点步长若没有小数部分会被当成整数在旧版本上可能是浮点。✅ 需要浮点结果时显式转换array_map(floatval, range(1, 5))。❌ 用range()生成数组键后忘了 PHP 的键类型规则 ——array_combine(range(1, 3), $values)得到的键是整数1, 2, 3不是字符串1,2,3PHP 数组会把纯数字字符串键自动转成整数。✅ 需要字符串键就显式转换array_map(strval, range(1, 3))或直接在键里加前缀。总结要点结论签名range(string\区间闭区间包含$end最后一个元素可能小于$end步长不整除时方向由$start与$end的大小决定不由步长的正负决定元素类型双字符串 整数步长 → 字节序列含浮点 → 浮点序列否则整数序列PHP 8.3.0 新增错误步长为 0、非有限值、递增区间配负步长均抛ValueError字符序列是按字节区间生成的range(A,z)会带进 6 个非字母字符内存一次性构造整个数组大区间应改用生成器或for循环一句话总结range()的方向由两个边界决定$step只控制间距记住它是闭区间、记住 PHP 8.3 起对非法步长不再「猜」而是抛ValueError再用生成器处理大区间它就是一个可靠的工具。

相关新闻

pytest实战:宏系统与PTZ云台控制的自动化测试

pytest实战:宏系统与PTZ云台控制的自动化测试

做软件这行的,早晚会碰上一个没法“手测”的项目。我印象最深的就是那套包含宏系统和 PTZ 云台控制的相机联动平台:宏命令能录能播,PTZ 控制有绝对定位、相对移动、连续调速、预置位,两者一叠加,输入组合瞬间变成几千种…

2026/11/7 4:26:02 阅读更多 →
2026年AI编程软件盘点:从代码补全到Agent的实战选型指南

2026年AI编程软件盘点:从代码补全到Agent的实战选型指南

2024年那波AI编程工具爆发的时候,市面上能打的还只有几个老面孔,到了2026年再抬头看,这个赛道已经卷成一片红海了。从单纯的代码补全,到能自己读Issue、改代码、跑测试的Agent,再到多智能体协作开发,工具形…

2026/11/14 7:26:21 阅读更多 →
WorkBuddy本质是MCP协议工作台,不是AI聊天框

WorkBuddy本质是MCP协议工作台,不是AI聊天框

1. WorkBuddy不是AI聊天框,而是你的“协议级工作台”很多人第一次点开WorkBuddy,下意识就把它当成另一个Claude或Cursor——输入指令、等它生成、复制粘贴。结果用了一周发现:响应慢、上下文总丢、插件装了不生效、本地文件读不出来……最后默…

2026/11/12 9:23:24 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/14 5:13:29 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/14 5:13:29 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/14 5:13:29 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/14 5:13:29 阅读更多 →

日新闻

周新闻

月新闻