• WordPressのアップロード先はwp_upload_dir()のpathとurlを分けて確認する

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を対応させてください。

戻る