メインコンテンツへスキップ

検索しても見つからないURL ― 五年前の設計が残っていた場所

| Alaudae.JP

サイトマップを作り直すたびに、もう存在しないURLが混ざる。

そんな状態がしばらく続いていました。クローラーを走らせると、四年も前に廃止したはずの製品ページのパスが、毎回きちんと拾われてくる。

/materia/fortuna15/... という形の、旧い階層です。今のサイトには、そんなページはありません。


まずは素直に探しました

最初に疑ったのは、記事の本文です。どこかの記事に古いリンクを書いたまま忘れているのだろう、と。

見つかりません。

次にメニュー、モジュール、テンプレートの設定。どれも空振りでした。

そこで最後の手段として、データベース全体を検索しました。phpMyAdminには、全テーブルをまたいで文字列を探す機能があります。ここに引っかからなければ、少なくともデータベースの中には無いということになる。

結果はゼロ件でした。

これで困りました。データベースに無い。記事にもメニューにも無い。それなのに、クローラーは毎回そのURLを見つけてくる。

どこかに在ることは間違いないのです。ただ、私の探し方では見つからない。


理由は、スラッシュ一文字でした

答えを先に書きます。

その値は、JSONの形式でデータベースに保存されていました。そしてJSONでは、スラッシュが `\/` という形にエスケープされて記録されることがあります。

つまり、データベースの中に実際に入っていた文字列は、こうでした。

    materia\/fortuna15\/

私が検索窓に打ち込んでいたのは `materia/fortuna15` です。バックスラッシュが入っていない。だから一致しない。

存在しているのに、検索では出てこない。そういう状態でした。

これはJoomlaに限った話ではありません。カスタムフィールドやプラグインの設定値をJSONで保存する仕組みなら、どのCMSでも起こり得ます。データベース検索で見つからないからといって、無いとは限らないのです。


犯人は、二〇二一年の私でした

見つけ方を変えて、データベースのダンプを取り出し、中を辿っていきました。

出所は、二〇二一年三月に公開した一本の記事でした。素材の単品ページに一覧を差し込むために作った、サブフォーム型のカスタムフィールドです。

六ミリ、十五ミリ、二十一ミリの三つの幅に、それぞれ五十三色分のリンクが入っていました。三本で百五十九件。

さらに厄介なことに、多言語化のために英語の翻訳テーブルにも同じものが入っていました。こちらも百五十九件。合わせて三百十八件のリンクが、五年前の階層を指したまま残っていたわけです。

サイトは何度も作り替えました。URLの構造も変えました。表示は今の形になっています。
それでも、フィールドの中に書き込んだ絶対パスだけは、誰にも触られないまま生き残っていました。

画面のどこにも出てこないので、気付きようがありません。気付かせてくれたのは、クローラーだけでした。


置換する前に、危ないところがありました

直す作業自体は単純です。古いパスを新しいパスに置き換えるだけ。

ただ、ここで一つ、危ないことに気付きました。

英語の翻訳テーブルには、本文中にmaterialという英単語が使われている行がありました。もし`materia`という文字列だけを指定して一括置換していたら、このmaterialも巻き込んで壊していたはずです。

一括置換は、短い文字列で指定するほど危険が増します。今回であれば、パス全体を指定するのが正解でした。

    materia\/fortuna15\/  →  perla\/15mm-width\/

エスケープされた形のまま、丸ごと置き換える。こうすれば、英単語のmaterialには触れません。

作業は三段階で進めました。まず置換前にSELECTで件数を数える。次にUPDATEを実行する。最後にもう一度SELECTで、古い方がゼロになり、新しい方が想定どおりの件数になっているかを確かめる。

結果は、古いパスがゼロ件、新しいパスが五十三件ずつ三本。英語側も同じで、巻き込まれかけたmaterialは無傷でした。


設計の話として

これは作業の話に見えて、設計の話だと思っています。

二〇二一年の私は、フィールドの中にリンクを直接書き込みました。その時は、それが一番早かったからです。実際、動きました。

問題は、その値が画面から見えない場所に沈んだことです。記事の本文なら編集画面で目に入ります。メニューなら管理画面に並びます。けれどサブフォームの中に入れた百五十九本のリンクは、開いて一つずつ確認しない限り、二度と目に触れません。

リンクをどこに持たせるか。これは見た目の話ではなく、後から直せるかどうかの話です。

今なら、記事IDを指定する形にするか、少なくとも相対的な指定にしておくでしょう。そうすれば、URLの構造を変えた時に道連れにならずに済みます。

サイトを作り替えるとき、私たちは見えているものを直します。見えていないものは、直しようがありません。
だから、作る時点で「これは後から見えるか」を考えておく必要があるのだと思います。


最後に、実務的なまとめ

  • データベース全体検索でヒットしないからといって、存在しないとは限らない
  • JSONで保存された値は、スラッシュが `\/` にエスケープされている場合がある
  • 見つからない時は、ダンプを取り出して中を直接見るのが早い
  • 一括置換は、短い文字列を指定するほど危険。パス全体など、長く一意な形で指定する
  • 置換の前後にSELECTを挟んで件数を確認する

見つからないものを探して時間を溶かした一日でしたが、原因が分かってしまえば、なんということはありません。同じところで止まっている方の役に立てば幸いです。