Wordpress上でajax経由で関数をactionさせる時はadmin-ajax使うといいよ!
どうもふうや(@fwww0707)です!
昨日こんな記事を書きました!
自分用に備忘録したためかなり乱雑な記事になっていますが、その記事の末尾にちょろっとお話したWordpressのadmin-ajaxについて今日は言及、コードの解説、使い方についてお話しようと思います。
※間違った表記、理解がありましたらご指摘して頂けると幸いです
※はてなブログの仕様なのか配列の括弧が正常に表示されていない箇所がありますが文章に表記していますのでご理解ください
Wordpressのadmin-ajaxとは何か?通常のajaxとは何が違うのか
通常のajaxについての説明は割愛させていただいて、Wordpressには独自のajaxシステムが存在します。
そのファイルは
/wp-admin/admin-ajax.php
に存在します。
このファイルのソースコードを読めば分かる通りadmin-ajax.phpにリクエストを投げれば、Wordpressに登録されている任意の関数をactionさせることが出来ます。
javascript及びjQueryなどで扱う通常のajaxはPHPファイルにリクエストを投げて処理結果を保存したり受け取ったりと出来る訳ですが、Wordpress標準装備のadmin-ajaxはそれ以上に利便性が高くて便利です!
予めWordpressに登録させている関数をactionできる
通常のajaxだと別途phpファイルを用意しなければなりません。
ajaxさせるために個別のphpファイルを毎回用意するのは別に面倒ではありませんが、ajax専用のphpファイルを多数管理していると話は別です。
ファイル数が多くなると管理も面倒になってしまいます。
なのでadmin-ajaxはWordpressを利用しているユーザーにとって必見な訳です。
前述したとおりadmin-ajaxは予めWordpressに登録されている関数をactionするシステムですので、functions.phpやプラグインファイルに記述されていても(どこからでも)呼び出せる訳です。
要するにajax専用のphpファイルを用意する必要が無くなり、一つのファイル(関数単位)で処理を管理することが出来るようになります。
admin-ajaxはどんな時に利用するのか
admin-ajaxは、FormをsubmitさせてPOSTをしupdate_option()などでWordpressのDB(データベース)へデータを格納する処理の場合や、ajaxを利用しリアルタイムでデータベースへアクセスしその結果に応じた表示をさせたい場合などに利用することが多いです。
admin-ajax経由でデーターベースにデータを保存する利便性
admin-ajax(通常のajaxでも同様)はDOM要素としてformタグなどを用意する必要がありません。
よって、ページ内に散らばっている任意の要素や文字列を自由にデータとして扱うことができるようになります。
またsubmitボタンをクリックさせてデータを投げる必要がありませんので、ページをリロードさせたくない場合でもその利便性を発揮します。
実際にWordpressのadmin-ajaxを利用してみよう
リクエスト送信先は決まって"admin-ajax.php"です。
個人で利用する場合は直接リクエスト先のurlを記述すれば問題ありませんが、プラグインやテーマとして配布する場合はホスト名が同じではありませんので、phpファイル上にインラインで次のように"admin-ajax.php"へのurlを定義することを推奨します。
gist67aced28afe3fff5064ad7f885b65e5d
ここからはサンプルコードを提示します。
使用用途に応じてコードを編集しご利用ください。
任意のテキストをadmin-ajax経由でリクエストしたい
配列ではなく任意のテキストをadmin-ajaxにリクエストしたい場合は、次のようにカキカキします。
gist83c8e793ce480ea95ffcc2716d5d3fbb
dataTypeはtextでtype(メソッド)は指定しません。
urlは先程定義したadmin_ajax_urlで、actionにはWordpressに登録させている関数名を記述します。
text_testというのはphp側で受け取ったときの変数名で、textはjavascript上で定義されている変数(配列ではない)のことを指します。
secureに記述されている
<?php echo wp_create_nonce('text_test_ajax ') ?>
については後で解説します。
これはCSRF対策でセキュリティ上定義することを推奨するものです。
テキストではなく配列をadmin-ajax経由でリクエストしたい
テキストではなく配列をadmin-ajaxにリクエストする場合は、次のように利用します。
gistf02cb1ef40404c8298f8b7f87ff5147d
urlは先程と同じくこの記事で既に定義したadmin_ajax_urlを指定しています。
action、secureについてはテキストをadmin-ajax経由でリクエストを送信する時と仕様は変わりありませんので割愛させていただきます(詳しくはテキストをadmin-ajax経由でリクエストする際の解説をお読みください)
配列をajax経由でphpファイルにリクエストを投げる場合と同じく、phpで認識させる変数には配列の括弧を付与する必要があります。
javascript側のarrayは配列で定義された変数です。
admin-ajax経由で関数をactionする方法はこれ!
プラグインファイル内でもテーマ内のfunctions.phpでも良いので次の関数を定義します。
giste66b0e423832b73ba9930c326fe62dd3
上記の例ではテキストをadmin-ajax経由でリクエストされ、関数がactionされた場合のコードです。
check_ajax_referer('text_test_ajax','secure');
というのはadmin-ajaxにリクエストを送信する場合に定義した
<?php echo wp_create_nonce('text_test_ajax ') ?>
でCSRF対策(セキュリティ対策)でリクエストのチェックを行っています。
※CSRF対策の解説は割愛させていただきます
check_ajax_refererの第一引数はwp_create_nonceで定義したチェック用の文字列を、
第二引数にはチェックする際の認識文字列を定義します。
第二引数がsecureで無い場合はadmin-ajaxでリクエストを送る際のdata配列のsecureの箇所を任意の文字列にします。
admin-ajaxでリクエストを送る際にtype(メソッド)を指定しなかった理由はPHP側でメソッドをREQUESTとしてデータを受け取るためです。
少なくとも僕の環境ではjavascript側でtypeをPOSTやGETに指定しても、PHPへのデータの受け渡しが正常に行なえませんでした。(もちろんPHP側で$_POSTや$_GETで受け取ろうとしてでもです)
上記のコードの場合
$_REQUEST['text_test']
にjavascriptから受け取ったデータが格納されていますので、
$text = $_REQUEST['text_test'];
などとし柔軟にデータを扱いましょう。
admin-ajax経由で受け取ったデータが配列の場合は次のように扱います。
$array= $_REQUEST['array_test'];($arrayの後に配列の括弧が必要です)
PHP側でも配列として定義する必要がありますので注意が必要です。(既に解説した「配列をadmin-ajax経由でデータを受け渡しする」でリクエストをする際に定義したarray_testの例です)
PHP側で受け取る際は、
array_testとする必要がありませんのでこちらも注意が必要です。(配列の括弧は必要ないということ)
アクションフックには
wp_ajax_関数名
及び
wp_ajax_nopriv_関数名
を登録します。
wp_ajax_はログインユーザーが関数をactionさせる場合に利用し、wp_ajax_nopriv_は非ログインユーザーが関数をactionさせる場合に利用します。
詳しくはadmin-ajax.phpの83行から113行目に記述されています。
関数名というのはこの処理を施している関数を指します。
上記の例の場合だと関数名が"text_ajax_test"ですのでアクションフックには、
wp_ajax_text_ajax_test
と
wp_ajax_nopriv_text_ajax_test
を登録しています。
このように指定しないといけないのは、Wordpressのadmin-ajaxの仕様ですので注意してください。
詳しくはadmin-ajax.phpの74行目から79行目に書いてあります。
まとめ
長々とWordpress独自のadmin-ajaxについてのコード解説や言及を行ってしまいましたが、これほどまでに丁寧に解説されているサイトはあまり無いと思います笑笑
←自画自賛してしまいすみません!
Wordpressのadmin-ajaxを利用したかったけれど挫折してしまった方や今後プラグイン開発やテーマ開発などで導入して利用されたい方は是非この記事を参考にしてください。
最後まで読んでいただきありがとうございました!!