2014年のPHP一時修正が2000万回近くインストールされ、本日廃止します
My temporary PHP fix from 2014 has nearly 20M installs. Today I'm deprecating it (jakeasmith.com)
要約
著者は2014年、AOLのCMS移行のために一時的なPHP関数を作成しました。この関数は1〜2年で使われなくなるはずでしたが、Packagist経由で2000万回近くインストールされ、現在も多くのプロジェクトで使用されています。著者は数年後にこのパッケージを再発見し、バグの存在や、より優れた代替手段(PHP LeagueのURIライブラリやPHP 8.5の標準API)の登場を踏まえ、この一時的な修正を廃止することを決定しました。
全文翻訳
私の2014年のPHP一時修正パッチが2000万近くインストールされている。今日、私はそれを非推奨にします。
12年前、私はAOLのコンテンツ管理システム(CMS)のつなぎとして、174行のPHPコードを書きました。他の誰かが同じパッチを必要とするかもしれないと思いPackagistに公開したところ、以来、なんと2000万回近くインストールされています。今日、私はそれを非推奨としました。
一時的なシム(Shim)
2014年、私たちはAOLのCMSをPHP 5.2から5.3へアップグレードしている最中でした。そのアップグレードの一環として、http_build_url()という関数を提供するpecl_http拡張機能のバージョン1を廃止することになりました。CMSは多くのURLを扱いますが、私たちのCMSではそれが数十箇所で呼び出されていました。私はそれらのコードを変更するつもりはありませんでした。その関数は再現するのが十分簡単に見えたため、私は独自のhttp_build_url()を作成しました。これは、実際の関数がまだ存在しない場合にのみ定義されるようにしました。古いコードは何も変更されていないかのように動作しました。
当時Composerが普及し始めていたため、共有は容易でした。私はこれが1、2年で役目を果たし、PHPコミュニティがより良いものに移行するだろうと考えていました。
それだけのインストール数
しかし、それは一時的なものではありませんでした。Packagistから2000万回近くインストールされ、現在でも月に40万件以上のインストール数を獲得しています。
[画像: 2026年9月15日時点でのjakeasmith/http_build_urlのPackagistインストール統計:総インストール数19,864,271件、過去30日間で401,308件。日々のインストール数は2014年のほぼゼロから2026年には1日あたり約13,000件まで着実に増加しています。]
そして、Composerだけが全体像の一部ではないことがわかりました。WPML、WordPress向けの市場をリードする多言語プラグインは、このポリフィル(polyfill)を直接コードベースにバンドルしており、WPMLによると150万以上のサイトにインストールされています。ドメイン名ライブラリidna-convertもこれに依存しており、それがSPIP(フランスのコンテンツ管理システム)のソースに同梱され、DebianやUbuntuにパッケージ化されることになりました。これらすべてを合わせると、私のコードを実行しているウェブサイトをあなたが訪問した可能性はかなり高いでしょう。
ここまで広がるとは想像もしていませんでした。
再び向き合う
数ヶ月前、何年もぶりにパッケージを確認したときに、それがどれほど広範囲に及んでいるかに気づきました。ユーザーがいることは知っていました。2021年までにはPHPから離れていましたが、ダウンロード数は驚くほど多く、新しいメンテナーを募集しました。3人が申し出てくれました。募集の直後、私たちは予期せず家族を亡くし、しばらく私たちの世界はひっくり返りました。私はフォローアップをしませんでした、それは私の責任です。状況が落ち着いた頃には、他の目標が優先され、私は何年もこのパッケージのことを忘れていました。
数字に加え、GitHubのイシューがいくつかありました。その中には、末尾にスラッシュがあるURLにパスを結合すると、パスからすべての「a」という文字が削除されるというものもありました。まっすぐにはいかないものです。// Workaround for trailing slashesというコメントの下で、私のコードはパスに「a」を追加して常に最後のセグメントを切り取れるようにし、その後find-and-replaceで切り取ります。パスがスラッシュで終わる場合、その最後のセグメントは単なる「a」であり、find-and-replaceはパス内の他のすべての「a」も一緒に削除してしまいます。このバグがこれほど長く見過ごされていたとは信じられません。
そこで、私は決断を下さなければなりませんでした。ほぼ10年ぶりにPHPの世界に戻り、申し出てくれた人の一人にパッケージを引き継ぐか、そのまま放置するか、です。
どれでもない
これは常に一時的なものであるはずだったので、私はそれを引退させます。PHP LeagueのURIライブラリは長年コミュニティの答えとなっており、PHP 8.5には言語自体に標準準拠のURI APIが搭載されました(jawiraさんに教えてもらいました)。どちらも2014年の174行のシムよりも優れています。パッケージを維持することは、誰もが行うべき移行を遅らせるだけです。また、引き継ぎはそれにリスクを加えることになります。申し出てくれた人を疑っているわけではありませんし、ozhさんはYOURLSのためにフォークを維持してくれています。しかし、下流の誰も検証していない、広くインストールされているパッケージは、まさに攻撃者が探しているものです。Veritasiumのxz Utilsバックドアに関する動画は、それがどのように展開されるかの最良の説明です。
パッケージは引き続きインストールできますが、欠落している「a」のバグを含め、新しい修正は行われません。これほど長い間変更がない場合、1行の修正でさえ、誰もサポートする人がいない状況で、誰かに意図しない結果をもたらす可能性があります。READMEに切り替え方法が示されています。
私はこのコードを、私自身と、同じ移行を経験している他の誰かのために、苦痛な移行を緩和するために書きました。プルリクエストを送ってくれた方、引き継ぎを申し出てくれた方、そして私がもう読んでいない後もイシューを報告し続けてくれた方々に感謝します。一時的な修正としては、良い走りでした。
P.S. AOLのCMSをこの「一時的な」ポリフィルから移行することはありませんでした。プラットフォーム全体が2020年頃にシャットダウンされるまで、そこで稼働していました。