2014年的临时PHP修复,竟有2000万次安装
My temporary PHP fix from 2014 has nearly 20M installs. Today I'm deprecating it

2014年,我为了应对AOL的CMS升级,随手写了174行PHP代码作为临时补丁,本想用一两年就淘汰。没想到这个名为http_build_url的polyfill在Packagist上被安装了近2000万次,甚至被WPML和Debian等主流项目打包。直到最近我才发现代码里藏着一个奇怪的bug:当路径以斜杠结尾时,会错误地删除所有字母“a”。面对PHP 8.5原生API的成熟和The PHP League URI库的完善,我决定正式废弃这个“临时”项目。维护它只会延缓大家向更优方案迁移的脚步,而转交维护权又可能引入安全风险。感谢所有使用过它的人,这场意外的长跑到此结束。
一个被广泛安装却由未经下游验证的新维护者接手的项目,正是攻击者梦寐以求的目标。
HN 评论区
101- Sander_Marechal
没有什么比一个行之有效的临时修复更永久了。
- jakeasmith
作者在此,乐意回答任何问题。我从未想过一个 http_build_url 的 polyfill 会如此流行。12 年过去了,废弃它感觉是正确的决定,尤其是考虑到社区和 PHP 本身提供的这些新选择。
- swiftcoder
> 在一条写着 // Workaround for trailing slashes 的注释下,我的代码会在路径末尾追加一个“a”,确保总有一个最后一段可以被截断,然后用查找替换将其截去。当路径以斜杠结尾时,最后一段就只是那个“a”,而查找替换操作会把路径中其他的“a”也一并带走。
这简直是顶级操作。达到了 left-pad 那种“我们干脆在自己的代码库里实现一些琐碎函数”的水平。
(我并非在贬低作者——这确实完美解决了他的使用场景。只是之后那些依赖它的家伙们……)
- amhoab
我们以前在 AOL 共事过。很高兴在这里看到你;希望你一切顺利!
- laruss5
对于一个拥有如此庞大安装量的包,有没有一个最终版本能在废弃声明中打印出迁移选项?多年后,人们还是会通过旧的 Stack Overflow 答案找到它。
- zackmorris
PHP 在扩展和 PECL 模块方面搞砸了,根源在于它作为 Web 服务器语言的出身。在托管环境中,由于管理员没有安装或启用某些功能,PHP 往往不提供我们认为的基本功能。因此,存在这些一次性的小包来绕过这些烂摊子也就说得通了。
不过它依然是我最喜欢的语言,因为它最接近 Shell 语言,却拥有 C 风格的语法(除了 Perl,那是一种只写不读的语言,难以阅读,不幸的是它还启发 Ruby 继承了一些反模式)。
我经常梦想着能写出一门现代黑客语言,融合一切优点,比如函数式编程、高阶方法、默认 const、并行性、同步阻塞而非异步非阻塞并发等等。它还会撤销 PHP 5+ 引入的按引用传递的那些埋雷,回归到数组的按值传递、写时复制风格。这也是我为什么真的无法支持像 Hack 这样的尝试,它们只是引入了带有自身问题的新标准。
其中的洞见在于:LLM 是在绕过主流语言和框架的局限性,而不是从头挑战假设并构建更好的基础。
- AltruisticGapHN
这个仓库应该被归档吗?
我很少看到有人使用这个功能,但 GitHub 上有大量仓库本质上已经死了。
- hk__2
> 除了这些数字,还有一小部分 GitHub 问题,其中包括一个:当将路径拼接到带有尾随斜杠的 URL 上时,路径中所有的字母“a”都会被删除。