WordPressでAjax でファイルをuploadする(非ログインユーザー可)

動機

WordPress でフォームから一度にファイルを複数アップロードすると画面遷移が重たくなります、対策としてAjaxにて非同期でアップロードします。

ログインしていない一般のサイト閲覧者がフォームからアップロードを想定しており、見積フォームなどで使う用途で作りました。

とはいえ、ほぼ出来のコードを組み合わせております(ページ下部に参考サイトを紹介させていただいております)

手順

STEP1

functions.php にて

wp_localize_script()

でPHPからJSに情報を渡す段取りをする。

wp_enqueue_script()

でJSファイル(STEP3)を登録する

STEP 2

functions.php にて

do_action( “wp_ajax_{$action}” )

で、Ajaxを引き受ける関数をPHPにて記述。

※上記の my_wp_ajax() 

STEP 3

AjaxするJSファイルを用意、設置する。
https://blog.spicadots.com/2020/05/wordpress-file-upload-with-ajax/

を参考に、upload-image.js とした

STEP 4

投稿、固定ページにHTMLフォームを設置

ワンポイント説明

HTML部分
formタグが無いのが特徴です、フォームタグの入れ子など配慮無用となります。

upload-image.js にて

let data = new FormData;

で、新しいFormData オブジェクトを生成しています。

Ajaxを受け付ける関数、my_wp_ajax()について
POSTされたデータを保存するのに、Wordpress の 

wp_upload_bits()

を使っています。

返り値は配列で、 ‘error’ key を見ることで成功を判定できます。

wp_upload_bits() は、記事に添付することなく、ファイルを uploads ディレクトリ配下へ保存してくれます。
同名ファイルの場合も、ファイル名-1.jpg、ファイル名-2.jpg のように枝番を自動で作ってくれます。

セキュリティ部分

wp_create_nonce( $action );

WordPress公式

でnonceを生成・使用して

check_ajax_referer( $action, $query_arg, $die )

で、チェックしています。

参考にさせていただいたURL

WordPressでファイルアップロードをAjaxでやる方法
JSに関して、こちらの情報を参考にさせていただきました。

こちらのページでは、ファイルのアップロードは

async-upload.php

を使っておられます。この方法は、

ありがとうShizumiさん

WordPress Create Upload Files and Directories
wp_upload_bits()

でのファイルアップロードと保存について、参考にさせていただきました。

返り値は

array(4) {
    ["file"]=>
    string(84) "/home/user/wp/wp-content/uploads/2022/12/aaaaaa.jpg"
    ["url"]=>
    string(67) "http://xxxxx.com/wp/wp-content/uploads/2022/12/aaaaaa.jpg"
    ["type"]=>
    string(10) "image/jpeg"
    ["error"]=>
    bool(false)
}

です。

ありがとうJEFF STARRさん。

ご相談・お問合せ

お気軽にどうぞ。