应使用 php 8.5.7 的 uri\rfc3986\uri 类替代 parse_url(),它严格遵循 rfc 3986、修复两个 cve 漏洞、支持显式验证与规范化,并要求通过对象方法操作 uri 组件。

直接用 PHP 8.5.7 内置的 URI 扩展,而不是继续依赖 parse_url() —— 这是当前最安全、最标准的做法。8.5.7 不仅修复了 URI 解析相关的两个 CVE 安全漏洞(CVE-2026-44927 和 CVE-2026-44928),还让 RFC 3986 模式真正可用、稳定且默认受控。
RFC 3986 模式需显式启用
PHP 8.5 新增的 Uri\Rfc3986\Uri 类严格遵循 RFC 3986,但不会自动替代旧函数。你必须主动使用它:
- 不推荐:
parse_url($url)—— 行为宽松、不校验、易出错,已不适用于安全敏感场景 - 推荐:
use Uri\Rfc3986\Uri; $uri = Uri::createFromString($url); - 该类会拒绝明显非法输入(如缺失 scheme 的绝对 URI),并在解析时保留原始编码与规范解码的区分,避免因自动转义导致的比较偏差
关键操作要走对象方法,别拼字符串
拿到 Uri 对象后,所有读取和修改都应通过其方法完成,杜绝手动拼接:
- 获取组件:
$uri->getScheme()、$uri->getHost()、$uri->getPath()(返回已标准化的值) - 修改组件:
$newUri = $uri->withHost('api.example.com')->withPort(443)->withPath('/v1/users')(返回新对象,原对象不可变) - 比较两个 URI 是否相等:
$uri1->equals($uri2)—— 这个方法已修复 CVE-2026-44928,能正确识别语义相同但编码不同的 URI
验证和规范化必须成对使用
仅解析不够,还需结合验证逻辑确保输入可信:
- 先用
Uri::isValid($url)判断是否符合 RFC 3986 语法(非空 scheme、合法 host 等) - 再调用
$uri->normalize()获取规范形式(如小写 scheme、去除默认端口、路径折叠等) - 若用于缓存键或访问控制,务必使用
$uri->normalize()->toString()作为唯一标识,而非原始输入 - 注意:
filter_var($url, FILTER_VALIDATE_URL)仍可作为轻量前置过滤,但它不等价于 RFC 3986 验证,不能替代Uri::isValid()
升级后务必重测业务逻辑
尤其关注以下场景,它们直接受 CVE 修复和新扩展影响:
- 基于 URI 做白名单校验的跳转功能(如 OAuth redirect_uri)
- 用 URI 字符串做缓存 key 的服务(如 API 响应缓存)
- 请求去重或幂等判断中依赖 URI 相等性的地方
- 任何调用了
parse_url()并自行拼接、比较或编码的代码段
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











