PHP无原生稀疏表,需用关联数组模拟:键任意、未设键不占内存;用array_key_exists判断存在性,foreach遍历仅真实项;范围查询需额外排序或外部存储。
PHP 本身不提供「稀疏表」(sparse table)这种数据结构——它不是像 array 或 SplFixedArray 那样的内置类型。所谓“稀疏表”,通常指逻辑上大范围索引(如 0–10⁶)、但实际只存储少量非空值的结构。你在 PHP 中实现它,本质是用普通数组或对象模拟,关键在于**避免预分配内存**、**按需存取**、**跳过空槽**。
PHP 的 array 是哈希表实现,天然适合稀疏场景:键可以是任意整数(包括很大或负数),未设置的键不占内存。这是绝大多数 PHP 稀疏需求的实际解法。
$table[1234567] = 'value' 赋值,不初始化整个范围isset($table[$key]) 或 array_key_exists($key, $table)(注意二者对 null 处理不同)foreach ($table as $index => $value),只迭代真实存在的项range(0, 999999) + array_fill 初始化,那会立刻吃光内存$sparse = []; $sparse[0] = 'start'; $sparse[1000000] = 'end'; // 中间 999998 个索引根本不存在 var_dump(count($sparse)); // int(2) var_dump(isset($sparse[500000])); // bool(false)
纯关联数组不支持快速查找「小于等于某 key 的最大已存键」或「下一个非空位置」这类操作。若业务涉及区间扫描(比如时间戳稀疏日志、坐标格网),就得自己封装逻辑:
ksort() 维护键有序(仅在写入后偶尔调用,避免每次插入都排序)array_keys($table) 提取所有键,再用 array_filter() 或二分查找(array_search 不适用,得手写)定位SplMinHeap 存键,或用 Redis 的 ZSET 做外部稀疏索引这是最容易踩的坑:如果某个键被显式设为 null,isset($table[$key]) 返回 false,而 array_key_exists($key, $table) 返回 true。稀疏表中你往往关心“是否被赋值过”,而非“是否为非 null”——所以多数情况该用 array_key_exists。
$t[10] = null; → isset($t[10]) 是 false,array_key_exists(10, $t) 是
true