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