负数offset表示从字符串末尾倒数定位起始位置:substr("hello", -1)得"o",substr("abc", -5)因越界返回空串;处理多字节字符应使用mb_substr并指定编码。

substr 中的负数 offset 表示从字符串末尾开始倒数定位起始位置。
负 offset 的实际含义
当 $offset 是负数时,PHP 不是从开头数,而是从字符串最后一个字符往回数:
-
substr("hello", -1)→ 取倒数第 1 个字符 →"o" -
substr("hello", -2)→ 从倒数第 2 个字符(即"l")开始,取到末尾 →"lo" -
substr("hi", -2)→ 倒数第 2 个就是开头,等价于substr("hi", 0)→"hi"
越界时返回空串,不是 bug
如果负 offset 的绝对值超过字符串长度,起始位置就不存在,函数会静默返回空字符串 "":
-
substr("abc", -5)→ 字符串只有 3 个字符,倒数第 5 个不存在 → 返回"" - 这不是错误或异常,是 PHP 官方定义的明确行为,属于「静默容错」设计
和 mb_substr 的关键区别
普通 substr 按字节计算,对中文、emoji 等多字节字符容易出错:
立即学习“PHP免费学习笔记(深入)”;
-
substr("你好", -1)可能只截出半个 UTF-8 字节 → 乱码 - 处理中文应改用
mb_substr("你好", -1, null, 'UTF-8'),它按字符计数,逻辑一致但更安全
怎么避免踩坑
若需稳定使用负 offset,建议提前校验:
- 用
strlen($str) + $offset算出实际起始索引(结果为负就说明越界) - 或统一转成非负:
$start = max(0, strlen($str) + $offset) - 对多字节内容,直接换用
mb_substr并显式传'UTF-8'



















