【ITニュース解説】Finding duplicate images in a WordPress media library, without flagging WPML translations
2026年09月21日に「Dev.to」が公開したITニュース「Finding duplicate images in a WordPress media library, without flagging WPML translations」について初心者にもわかりやすく解説しています。
ITニュース概要
WordPressの重複画像検出プラグイン開発では、ファイル名ではなくファイル内容で重複を特定する重要性が判明。WPMLなど多言語プラグインの言語別画像は重複とせず、ディスクに存在しない画像も検出する工夫が必要だと、実際の開発で学んだ。
ITニュース解説
WordPressのウェブサイトを運営していると、たくさんの画像がメディアライブラリに蓄積されていく。しかし、同じ画像が重複してアップロードされていることに気づきにくいという課題がある。この記事では、WordPressプラグイン「Filikod」の作者が、重複画像を検出する機能を実装する際に直面した具体的な問題と、その解決策について解説している。システムエンジニアを目指す人にとって、理論と現実のギャップを理解する上で非常に参考になる事例だ。
著者は、重複画像検出機能を開発した当初、いくつかの「単純な想定」をしていた。その一つは「重複画像には見分けやすい名前が付いているはず」というものだった。例えば、「photo.jpg」と「photo-1.jpg」のように、ファイル名が似ていれば重複だと判断できると予測していた。しかし、実際のクライアントサイトでこの機能を試したところ、この想定はすぐに誤りだと判明した。同じダッシュボードのスクリーンショットが、アップロードした担当者や時期が異なるために、全く異なるファイル名で複数回アップロードされているケースが頻繁に存在したのだ。WordPressの管理画面上では、これらが同じ画像であると自動的に認識する術はないため、何時間もメディアグリッドをスクロールしても気づかないことが多かった。
この経験から、画像の同一性を判断するためには、ファイル名ではなく「ファイルの内容」そのものを比較する必要があると著者は結論付けた。具体的には、ファイルのバイト列(データの中身)から「フィンガープリント」と呼ばれる一意の短い識別子(ハッシュ値とも呼ばれる)を生成し、このフィンガープリントが一致するかどうかで「完全に同じ画像」かどうかを判断する方法を採用した。これにより、ファイル名が異なっていても同じ画像を正確に検出できるようになった。ここで重要な注意点として、WordPress 5.3以降では、大きな画像をアップロードすると自動的に縮小されたファイルが使われることがあり、また画像最適化プラグインやWordPress内蔵のエディターなどによって、アップロード後にファイルの内容が変更される可能性があると指摘されている。そのため、フィンガープリントはファイルの変更に合わせて常に更新する必要があることも説明されている。
二つ目の想定は「同じファイルであれば、すべて同じ問題として扱えるはず」というものだった。これは特に、WPMLのような多言語対応プラグインを使っているサイトで問題となった。多言語サイトでは、一つの物理的な画像ファイルに対して、各言語のアタッチメント(添付ファイル情報)が別々に作成される。つまり、例えばフランス語版、英語版、スペイン語版のウェブサイトで同じ製品写真を使う場合、これらはサーバー上では同じ物理ファイルを指しているにもかかわらず、WordPressのデータベース上ではそれぞれ異なるアタッチメントとして記録されるのだ。これらを単純に「重複」として扱ってしまうと、例えば「スペイン語版の重複画像」を削除した際に、実際にはスペイン語ページの画像が表示されなくなるという深刻な事態が発生する。また、画像に設定する代替テキスト(altテキスト)の監査においても、多言語のアタッチメントに同じaltテキストが設定されていると、それが複数回検出されてしまい、誤って「重複するaltテキスト」というエラーとして報告されてしまう問題も発生した。
この問題の解決策として著者は、「翻訳セットは一つの画像として扱う」というルールを導入した。WPMLなどの多言語プラグインは、どの添付ファイルがどの言語の翻訳セットに属するかという情報を独自のデータベーステーブルやメタデータに保持している。そこで、これらの情報を効率的に取得するSQLクエリ(データベースを操作する言語)を利用して、同じ物理ファイルを指す複数のアタッチメントが、実は「多言語の翻訳セットの一部」であるかどうかを判断する仕組みを構築した。これにより、真に不要な重複画像だけが検出されるようになり、実際のクライアントサイトでは数百件あった重複グループが、最終的に29件の「本当に整理すべき重複」にまで大幅に減少したという。
三つ目の想定は「メディアライブラリに表示されているものは、すべてサーバー上にファイルが存在するはず」というものだった。しかし、長期間運用されたサイトや、何度か移行を経験したサイトでは、メディアライブラリには登録情報だけが残っているものの、対応する画像ファイルがサーバー上からすでに削除されているケースがあることが判明した。これらの「ファイルのないアタッチメント」は、WordPressの管理画面では一般的なアイコンとして表示されるだけで、ファイルがないことには気づきにくい。しかし、実際にこれらの画像がウェブページで参照されている場合、訪問者には壊れた画像として表示されてしまうため、ユーザーエクスペリエンスを大きく損なう原因となる。著者はこの問題に対し、ファイルが存在しないアタッチメントを一覧表示する機能を追加し、それがどのページで使われているかまで提示することで、管理者にとって非常に有用な情報を提供した。
さらに、多言語サイトでメディアの監査を行う際の重要な教訓も得られている。WPMLやPolylangのような多言語プラグインは、WordPressの管理画面で行われるデータベースクエリにフィルター(絞り込み)を適用することがある。これにより、管理者画面で現在選択されている言語に属するデータしか取得できず、メディアライブラリ全体の画像を正確に把握できないという問題が発生することがあった。著者のプラグインでも、当初はメディアライブラリの約3分の2の画像を見落としていたことが判明した。この問題を回避するためには、クエリを実行する際に suppress_filters というオプションを true に設定し、第三者プラグインによるフィルターを一時的に無効化する必要がある。これにより、全言語のメディアファイルを正確に取得・監査できるようになる。
最後に、著者のプラグインが「あえてしないこと」についても言及している。それは、検出された重複画像を自動で削除したり、関連するウェブページのコンテンツ内の参照を自動で書き換えたりしないという方針である。自動的な削除や書き換えは、思わぬバグやサイトの破損を引き起こすリスクが高く、ユーザーの不満につながりやすいからだ。プラグインはあくまで「情報提供」に徹し、どの画像を削除するか、どのように修正するかという最終的な判断は、利用者に委ねている。ただし、新しい画像をアップロードする際に、それがすでに存在するかどうかを警告する機能は提供しており、これにより重複の発生を未然に防ぎ、問題が大きくなる前に対応できるようにしている。
この記事は、ソフトウェア開発における「初期の想定」がいかに現実と異なるか、そしてそのギャップをどのように埋めていくかというプロセスを具体的に示している。特に、多言語対応という複雑な要素が加わることで、一見シンプルな機能の実装でも多くの考慮事項が必要になることがよく理解できるだろう。