WordPressのアップロード先はwp_upload_dir()のpathとurlを分けて確認する
公開日: 執筆:佐藤
wp_upload_dir()が返すpathはサーバー上の保存場所、urlはブラウザーから参照する公開先です。ファイルの存在確認にはpath、HTMLのリンクや画像参照にはurlを使います。
二つを文字列置換で相互変換してはいけません。WordPressの設定、マルチサイト、定数、フィルターによって、保存場所と公開URLの組み合わせは変わります。
pathとurlは同じ場所を別の形式で示す
WordPress 3.8のwp_upload_dir()は、アップロード先について六つの値を返します。
| キー | 内容 | 主な用途 |
|---|---|---|
path |
現在のサブディレクトリを含むサーバー上のパス | ファイルの読み書き、存在確認 |
url |
現在のサブディレクトリを含む公開URL | HTMLのhrefやsrc |
subdir |
年月別設定で追加される部分 | 基準位置との差の確認 |
basedir |
subdirを含まないサーバー上の基準パス |
アップロード領域内の位置計算 |
baseurl |
subdirを含まない公開URLの基準 |
アップロード領域内の公開先計算 |
error |
ディレクトリを用意できない場合のメッセージ | 処理を止める条件 |
たとえば、年月別フォルダーが有効で、subdirが/2014/02なら、pathはbasedirへsubdirを加えた保存先、urlはbaseurlへsubdirを加えた公開先です。
ファイル操作とHTML出力で使う値を分ける
同じファイル名を扱う場合も、サーバー上の位置と公開URLを別の変数へ入れます。
$uploads = wp_upload_dir();
if ( false !== $uploads['error'] ) {
return;
}
$filename = 'document.pdf';
$file_path = trailingslashit( $uploads['path'] ) . $filename;
$file_url = trailingslashit( $uploads['url'] ) . $filename;
$file_pathは、file_exists()など、サーバー上のファイルを扱う処理へ渡します。$file_urlは、ファイルが存在することを確認したあと、esc_url()を通してリンクへ使います。
if ( file_exists( $file_path ) ) {
echo '<a href="' . esc_url( $file_url ) . '">資料を見る</a>';
}
pathをそのままHTMLへ出すと、サーバー内部の位置が表示され、ブラウザーから開けません。urlをfile_exists()へ渡しても、サーバー上のファイル位置としては確認できません。
このコードは既存ファイルの位置を確認する例です。wp_upload_dir()自体は、指定したdocument.pdfを書き込んだり、ファイル名の重複を避けたりしません。ファイル作成の処理と、保存先の取得を分けてください。
年月別フォルダーではsubdirまで確認する
年月別フォルダーの設定が有効な場合、引数を省略したwp_upload_dir()はWordPressの現在時刻から年と月を取り、subdirへ加えます。特定の年月について調べる場合は、yyyy/mm形式の値を渡せます。
$uploads = wp_upload_dir( '2014/02' );
この場合、basedirとbaseurlはアップロード領域の基準を示し、pathとurlは/2014/02を含みます。すべてのファイルを基準位置から探したい処理と、指定月のファイルを扱う処理で使うキーを分けます。
年月別フォルダーが無効なら、subdirは空です。「必ず/年/月が付く」と決めてコードを書かず、返された値を使います。
パスからURLを組み立てない
wp_upload_dir()は、upload_path、upload_url_path、WP_CONTENT_DIR、WP_CONTENT_URL、UPLOADSなどから保存先と公開先を決めます。マルチサイトでは、サイトIDやファイル配信方式によっても値が変わります。最後にupload_dirフィルターが返り値へ適用されます。
したがって、サーバー上の/var/www/をドメインへ置き換えるような処理は、別の環境へ移したときに壊れます。pathとurl、またはbasedirとbaseurlを同じ呼び出しの返り値から取得します。
説明用の仮例では、保存先が/srv/site/wp-content/uploads/2014/02でも、公開先がhttps://static.example.com/media/2014/02になる構成があります。この場合、パスの文字列から正しいURLは作れません。
errorを確認してから処理を続ける
wp_upload_dir()は、対象ディレクトリがなければwp_mkdir_p()で作成を試みます。作成できない場合は、errorへ、親ディレクトリがウェブサーバーから書き込み可能かを確認するメッセージを入れます。
返り値を受け取ったら、pathより先にerrorを確認します。作成に失敗したまま別の書き込み処理へ進むと、本来の原因から離れた警告が増えます。
ただし、errorがfalseでも、個々のファイルを必ず書き込めるという保証にはなりません。対象ディレクトリがすでに存在する場合、wp_mkdir_p()はディレクトリの存在を確認して成功とします。実際の書き込み処理にも失敗時の分岐を用意します。
アップロード先を変更するときは、コードだけでなく、次の項目を記録します。
- 変更前後の
basedirとbaseurl - 年月別フォルダーの設定
UPLOADS定数とupload_dirフィルターの有無- ディレクトリの所有者と書き込み権限
- 既存ファイルの移動方法と、元へ戻す条件
制作会社へ作業を委託しても、アップロードファイルの保存場所と公開URLはサイト側で把握します。サーバー移転やバックアップ復元では、テーマのコードだけでなく、実ファイルとURLの対応が必要です。
最初の一手は、管理対象の環境でwp_upload_dir()の六つの値を一回だけ確認することです。認証情報やサーバー内部のパスを公開画面へ出さず、管理用の記録でpathとurl、basedirとbaseurlを対応させてください。
関連記事

