前提
ローカル開発中にPHPやフロント実装を詰めていく中で発生した不具合と修正の整理である。
特に修正が多かったのは以下の領域だった。
- 管理画面の独自メタボックス
- 画像アップロード
- フォルダ運用
- 削除・ゴミ掃除
- カスタム投稿の表示
- トップページ内のカルーセルや一覧表示
開発後半になるほど、単純な表示実装よりも、途中保存・削除・ドラッグ&ドロップ・仮保存状態・不正入力・同名ファイル衝突のような半端な状態への対処が増えていった。
1. 投稿保存前の画像をどう扱うか
問題
新規投稿や新規カスタム投稿では、タイトル未確定の段階でも画像アップロードができるようにしていた。
しかしそのまま正式フォルダに保存すると、次のような問題が起きやすかった。
- タイトル未確定のままフォルダが作られる
- 仮保存状態の名前でフォルダができる
- 保存エラー時に画像だけ残る
- 記事を作り直すと古い画像が混ざる
修正
保存完了前は、投稿IDベースの一時フォルダにアップロードし、正式保存時に最終フォルダへ移動する方式に変えた。
学び
「投稿がまだ確定していない段階」と「公開用の保存先」を分けないと、ローカル開発中にすぐ残骸が増える。
2. サムネ未設定での保存失敗と中途半端な状態
問題
記事やプロフィール系投稿では、一覧やトップ表示でサムネ画像を前提にしている箇所があった。
そのため、サムネ未設定のまま投稿すると
- 一覧表示が崩れる
- トップ表示で空要素になる
- 画像はアップロード済みなのに投稿だけ失敗する
- 戻ったあと、以前の作業で作られた画像フォルダが残る
といった問題が起きた。
修正
公開系ステータスではサムネ必須にし、未設定時は保存を止めて編集画面へ戻すようにした。
同時に、戻った際に残っている一時フォルダも掃除するようにした。
学び
「入力エラー時に投稿を止める」だけでは足りず、そこで作られた副作用(画像・フォルダ)まで片付ける必要がある。
3. 途中保存や保存失敗時のゴミフォルダ掃除
問題
テスト投稿を作成し、画像をアップロードしたあとに保存失敗や投稿やり直しを行うと、
- 過去の画像がフォルダに残る
- 一時フォルダが残る
- 同名タイトルで再作成したときに古い画像が混ざる
といった問題が起きた。
修正
メタボックス描画時・保存時・削除時に、不要になった一時フォルダや空フォルダを消す処理を入れた。
さらに、ゴミ箱移動や完全削除でも関連フォルダを消すようにした。
学び
投稿データだけを消しても、アップロードディレクトリ側は自動で整理されない。
そのため、削除フローにファイル掃除を明示的に組み込む必要があった。
4. 仮保存状態の扱い
問題
WordPress の新規投稿では、正式保存前に仮の投稿状態が発生する。
この状態のまま画像アップロードやフォルダ生成を行うと、
- 仮状態の名前で保存先が作られる
- 後でタイトル変更してもフォルダ名がずれる
- URLやメタ情報が古いまま残る
という問題が起きる。
修正
仮保存状態の名前は正式名として使わず、
- 空扱いにする
- 一時フォルダ扱いにする
- 正式保存時にタイトルベースのフォルダへ移す
という構成に変えた。
学び
WordPress の仮保存状態は、画像管理やフォルダ管理と非常に相性が悪い。
タイトル未確定の初期状態を前提にした設計が必要だった。
5. ファイル名衝突と上書き事故
問題
同じファイル名の画像を複数回アップロードしたときに、既存ファイルを上書きしてしまう危険があった。
修正
同名ファイルがあれば自動で連番を振り、
image-1.jpgimage-2.jpg
のように退避する実装を入れた。
学び
開発中は同じ画像を何度もアップロードしがちなので、上書き防止は早い段階で必要だった。
6. UI上では削除したのに保存後に復活する問題
問題
管理画面で「削除したつもり」の画像が、保存後にまた出てくることがあった。
これは、見た目上の削除と実ファイル削除のタイミングが分離していたため。
修正
削除対象を hidden フィールドに蓄積し、保存時にまとめて削除する仕組みに変えた。
これにより、
- UIの並び替え
- 削除
- 最終保存
を一貫して扱えるようになった。
学び
ドラッグ&ドロップUIを使う場合、見た目の状態と永続化の状態を明示的に同期する設計が必要だった。
7. 空フォルダ・孤立ファイルの整理
問題
画像を削除し切ったあとでも空フォルダだけ残る、投稿削除後も画像だけ残る、といったゴミが蓄積した。
修正
最後のファイルが消えたときに空フォルダを削除する関数や、投稿削除時に関連フォルダ・関連ファイルを一括で消す処理を入れた。
学び
ローカル開発では何度も作って壊してを繰り返すため、掃除しない設計だとすぐにディレクトリ構造が汚染される。
8. 不正なパス・危険な削除への防御
問題
アップロードや削除の処理は、フォルダ名やファイル名を受け取る以上、パストラバーサルや意図しないファイル削除の危険がある。
修正
以下のような防御を追加した。
-
..や/を含むフォルダ名を拒否 -
realpath()で実パスを解決 - 期待ディレクトリ配下かを確認
- 条件外なら処理中断
学び
開発中は「ローカルだから大丈夫」と油断しやすいが、削除系のAJAXは最初から防御を入れるべきだった。
9. 画像形式の揺れへの対応
問題
スマホやMac由来の画像では、JPEG/PNG 以外に HEIC / HEIF などが混ざることがあり、単純な判定ではアップロード失敗することがあった。
修正
許可画像形式を整理し、wp_check_filetype_and_ext() と拡張子 fallback を組み合わせて判定するようにした。
学び
開発者の想定する画像形式と、実際に運用で持ち込まれる画像形式は一致しない。
端末依存の画像を前提にした設計が必要だった。
10. フロント表示側のフォールバック強化
問題
一覧やカード表示で、画像を1種類のメタ値だけに依存していると、入力途中の投稿や移行途中の投稿で空表示が発生しやすかった。
修正
フロント側では画像取得に優先順位を持たせた。
例:
- カスタムサムネ
- 専用メタ画像
- featured image
- フォルダ先頭画像
学び
入力データは常に完全ではないため、表示側に複数のフォールバック経路を持たせることが、管理負荷の軽減にもつながった。