WordPressでAjaxを使う方法

2019-05-31WordPressAjax

WordPress で Ajax を使う機会があり調べたのでメモ。

WordPress で Ajax を使う方法は 2 つあり、 WordPress に標準で用意されている機能を使う方法と、自分で作る方法がる。
今回は、標準機能の「 /wp-admin/admin-ajax.php 」にリクエストを送信する方法を用いた。

/wp-admin/admin-ajax.php とは

Ajax は、画面( JavaScript )からサーバー( PHP )にリクエストを送り、サーバー側で何らかの処理をしてレスポンスを画面に返す。
POST や GET 通信とは異なり、このやりとりが非同期で行わられる(つまり画面遷移やリロードがない)。

WordPress ではないただの PHP + JavaScript プログラムであれば、 JavaScript 内に「 url:hoge 」のように Ajax のリクエスト先を書けばいいのだが、 WordPress の場合、 Ajax のリクエスト送信先は決まっていて、それが「 /wp-admin/admin-ajax.php 」である。

リクエスト送信先が「 /wp-admin/admin-ajax.php 」であることは、どこかで明示的に宣言しておく必要がある。
この宣言をすると、フロント側で送信先 URL を認識できるようになる。

フロントに伝えることができさえすればいいので、その方法はいくつかあるが(どの方法が適切か?ベストかはわからない)、 wp_head()wp_footer() を使ってアクションフックさせるとか、 wp_enqueue_scripts() でフックする方法、そして wp_localize_script() を使う方法が見つかった。

wp_localize_script() を使う方法

WP 公式ページに載っている方法

Ajax の Script を出力する

function.php
function my_enqueue() {
  // 特定のページのみで読み込む(ここでは、スラッグ「sample-page」という固定ページにアクセスすると読み込まれる)
  if ( is_page( 'sample-page' ) ) {
    // Ajaxの処理を書いたjsの読み込み
    wp_enqueue_script( 'ajax-script', get_template_directory_uri().'/js/myjs/my-ajax.js', array('jquery'), null, true );
    // 「ad_url.ajax_url」のようにしてURLを指定できるようになる
    wp_localize_script( 'ajax-script', 'ad_url',array( 'ajax_url' => admin_url( 'admin-ajax.php') ) );
  }
}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );

全てのページで Ajax を使えるようにしたいなら、「 if ( is_page( 'sample-page' ) ) { 」を消す

このコードを function.php に書くと、「 sample-page 」ページの footer 下に下記コードが生成される

<script type='text/javascript'>
/* <![CDATA[ */
var ad_url = {"ajax_url":"サイトURL\/wp-admin\/admin-ajax.php"};
/* ]]> */
</script>
<script type='text/javascript' src='サイトURL/wp-content/themes/テーマ/js/myjs/my-ajax.js'></script>

サーバー側( PHP )の処理

function.php
// サーバー側(PHP)の処理
function do_myajax() {
// DBから検索結果を取得する場合
// global $wpdb;
// $list = $wpdb->get_results("SELECT id, name, url, hoge FROM table",ARRAY_A);
	$list = array(
	 0 => array(
	   'id' => 1,
	   'name' => '名前',
	   'hoge' => 'ほげ1'
	 ),
	 1 => array(
	   'id' => 2,
	   'name' => 'メーメー',
	   'hoge' => 'hogehoge2'
	 ),
	 2 => array(
	   'id' => 3,
	   'name' => 'M',
	   'hoge' => 'ホゲホ'
	 )
	);
	header("Content-type: application/json; charset=UTF-8");
	echo json_encode($list);
	wp_die();
}
// ログインしているユーザー向け関数
add_action( 'wp_ajax_my_action', 'do_myajax' );
// 非ログインユーザー用関数
add_action( 'wp_ajax_nopriv_my_action', 'do_myajax' );

Ajax のアクションフックには、ログインユーザーと非ログインユーザー用の 2 つが用意されている。管理画面用の Ajax であれば、 wp_ajax_my_action だけを使えばよい

add_action の第一引数である、 wp_ajax_* 、または wp_ajax_nopriv_* の「*」の部分は任意のアクション名をつける。
このアクション名が、 Ajax の data: { 'action' : '(*部分のアクション名)' } となる。

第二引数には、作成したファンクション名(ここでは do_myajax )を書く。

フロント( Script )の処理

「テーマ/js/myjs/my-ajax.js」を新規作成した

my-ajax.js
jQuery(document).ready(function($) {
  $.ajax({
      type: "POST",
      url: ad_url.ajax_url,
      data: { 'action' : 'my_action' }  // 「wp_ajax_*」の「*」がaction名となる
    }).done(function(data){
      console.log(data);
      console.log("done...");
    }).fail(function(XMLHttpRequest, textStatus, error){
          console.log(error);
          console.log(XMLHttpRequest.responseText);
    });
});

WP の中では「 $ 」は使えないよ。
代わりに jQuery を使うか、 function($) のように明示的に書いておくと使える。

実行した結果、コンソールログに PHP から返ってきた配列が出力された

0: {id: 1, name: "名前", hoge: "ほげ1"}
1: {id: 2, name: "メーメー", hoge: "hogehoge2"}
2: {id: 3, name: "M", hoge: "ホゲホ"}

wp_footer() (または wp_head() )を使ってアクションフックさせる方法

Ajax のリクエスト先 URL の宣言

admin-ajax.php ( ajax 通信経路 ) への URL をフロントに伝える

function.php
function add_ajaxurl() {
?>
    <script>
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php'); ?>';
    </script>
<?php
}
add_action( 'wp_footer', 'add_ajaxurl', 1 );

wp_head にしてもいい。これにすると、フッター部分に URL が出力される

これで画面ソースの footer 下に出力される

<script>var ajaxurl='サイトURL/wp-admin/admin-ajax.php';</script>

サーバー側( PHP )の処理

function.php
function my_ajax_do(){
    // DBから検索結果を取得する場合
    global $wpdb;
    $res = $wpdb->get_results("SELECT id, name FROM tbl",ARRAY_A);
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode($list);
    wp_die();
}
add_action( 'wp_ajax_my_ajax_do', 'my_ajax_do' );
add_action( 'wp_ajax_nopriv_my_ajax_do', 'my_ajax_do' );

ARRAY_A をつけると、検索結果を連想配列で取得することができる

フロント( Script )の処理

画面のフッダーとかボディとかにコード挿入

<script type="text/javascript">
jQuery(document).ready(function($) {
  $.ajax({
      type: "POST",
      url: ajaxurl, // admin-ajax.php のURLが格納された変数
      data: { 'action': 'my_ajax_do' },
      dataType:'json'
    }).done(function(data){
      console.log("done...");
      console.log(data);
    }).fail(function(XMLHttpRequest, textStatus, error){
       console.log('失敗'+error);
       console.log(XMLHttpRequest.responseText);
    });
});
</script>

Posted by Agopeanuts