WPでボタンクリックでPHP実行しページ遷移無しでpost送信してJavascriptで結果を表示する方法

phpとjavascriptWordPress

コピペで出来る!ボタンクリックでphpを実行しJavaScriptを使ってその場で出力

どうもバカルダーです。今日はWPの記事ページの中でボタンをクリックしたらページ遷移無しでpost送信を行い、任意のPHPを実行し、javascriptを使って実行結果を記事上に出力する方法を紹介します。

ほぼコピペで出来るようなコードを紹介していきます。

デモ

まずは、どんな感じの事が出来るか例を挙げてみます。

試しに以下のラジオボタンの中から番号を選択してphpを実行するボタンを押してみて下さい。(選択しなくてもphpは実行されます)

1番  2番  3番  4番 
「phpを実行」ボタンを押すとここに実行結果が表示されます。

ボタンがクリックされてからのデータ移動の流れ

  1. ボタンクリック
  2. 任意のPHPファイルへ入力データをpost送信
  3. 入力されたデータを受け取ったphpファイルでif文を使って場合分けして出力
  4. javascriptを使ってページ遷移無しで結果を出力

必要な3種類(HTML,PHP,Javascript)のコードを準備

この機能を実装するには以下の3つのコード、ファイルが必要です。

  • フォーム用のHTML
  • 実行するphpファイル
  • ページ遷移無しで出力するためのJavascript

実行するPHPファイルを準備してアップロード

まずは実行するphpファイルを準備して、サーバーへアップロードします。

<?php
if($_POST['tuka']=="1ban"){
echo "1番が選択されました。";
}elseif($_POST['tuka']=="2ban"){
echo "2番が選択されました。";
}elseif($_POST['tuka']=="3ban"){
echo "3番が選択されました。";
}elseif($_POST['tuka']=="4ban"){
echo "4番が選択されました。";
}else{
echo "番号を選択してください。";
}
echo "<br>更新:".date("Y/m/d H:i:s");
?>

post送信されたデータに応じてif文で場合分けして出力しています。

$_POST[‘tuka’]の部分はformのname属性を記入、formのvalue属性に応じて結果を変えています。

phpファイルをサーバーにアップロード

そして、作成したphpファイルをサーバーにアップロードします。

この例では「test.php」というファイル名で「wpフォルダの直下」にアップロードしています。(wp-config.phpと同じ階層 )

wpフォルダ直下にphpをアップロード

フォーム用のHTMLを作成

次はフォーム用のHTMLです。これはWPの記事ページに直接書いていきます。

<form action="/test.php" method="post" id="AjaxForm">
<input type="radio" name="tuka" value="1ban">1番 
<input type="radio" name="tuka" value="2ban">2番 
<input type="radio" name="tuka" value="3ban">3番 
<input type="radio" name="tuka" value="4ban">4番 
<input type="submit" value="phpを実行" class="submit">
</form>
<div id="result">「phpを実行」ボタンを押すとここに実行結果が表示されます。</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" async></script>

通常のpost送信するためのコードです。[action=”/test.php”]には実行するphpファイルのパスを記入します。

後のjavascript用にフォームと結果表示部分にidを設定しています。 jqueryを読み込むのを忘れると動きませんので注意して下さい。

ページ遷移無しで結果を表示するためのjavascriptを準備する

最後にページ遷移無しで結果を表示させるためのjavascriptを書いていきます。

$('#AjaxForm').submit(function(event) {
    // HTMLでの送信をキャンセル
    event.preventDefault();
    var $form = $(this);
    var $button = $form.find('.submit');
    $.ajax({
        url: $form.attr('action'),
        type: $form.attr('method'),
        data: $form.serialize(),
        timeout: 10000,  // 単位はミリ秒
        // 送信前
        beforeSend: function(xhr, settings) {
            // ボタンを無効化し、二重送信を防止
            $button.attr('disabled', true);
$("#result").text("")
        },
        // 応答後
        complete: function(xhr, textStatus) {
            // ボタンを有効化し、再送信を許可
            $button.attr('disabled', false);
        },
        // 通信成功時の処理
        success: function(result, textStatus, xhr) {
            // 入力値を初期化
            $form[0].reset();
            $("#result").append(result);
        },
        // 通信失敗時の処理
        error: function(xhr, textStatus, error) {
            alert('エラー暫くたってからお試しください。');
        }
    });
    // …
});

このjavascriptコードで行われている事

  • ボタンクリック後にページ遷移をキャンセル
  • id=AjaxFormのボタンがクリックされて、データの送信が完了するまではボタンを無効にして、データの送信が終われば再度有効に。
  • データ送信が完了したら既に入力されたデータをリセット
  • 実行結果をid=resultの部分に代入
  • データ通信エラーの場合の処理

javascriptを書く場所は/bodyタグの直前で良いと思います。

cocoonテンプレート使ってるなら カスタムJavaScript に書くのが便利

当ブログのように「cocoon」というテンプレートを使用しているのであれば、記事編集ページの下部の「カスタムJavaScript」の部分に記入しましょう。

cocoonでカスタムjavascript

このようにすることで他のページで読み込まれることが無くなるので、関係ないページで読み込み速度が遅くなるのを防げます。

応用例:受信したデータに応じてAPIからデータを取得&出力

応用例として、実行するphpでAPIからデータを取得して、post送信されたデータに応じて出力する機能を作りました。

具体的には以下のページの「XRPリアルタイムレンディングレートを取得する」ボタンです。

選択した通貨に応じて仮想通貨取引所「Bitfinex」「poloniex」のAPIデータからリアルタイムの貸し出しレートを表示しています。

postで受信したデータに応じてAPIからデータを取得して出力するためのPHPコード

以下が実際のPHPコードです。APIからデータを取得するのにcurl関数を使っています。参考にしてください。

<?php
function lend($name){
$ch = curl_init(); //開始
$url="https://api.bitfinex.com/v1/lends/".$name;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す

$response =  curl_exec($ch);
$result = json_decode($response, true);
echo "Bitfinex : ".$result[0]["rate"]."%<br>";
curl_close($ch); 

$ch = curl_init(); //開始
$url="https://poloniex.com/public?command=returnLoanOrders&currency=".$name;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  // curl_execの結果を文字列で返す

$response =  curl_exec($ch);
$result = json_decode($response, true);
$xrp=$result["offers"][0]["rate"];
$xrp2=$xrp+1;
echo "Poloniex : ".round(($xrp2**365-1)*100,4);
echo "%<br>";
curl_close($ch);
echo "コインチェック : 1~5%<br>GMOコイン : 5%";
}

if($_POST['tuka']=="XRP"){
echo "<h4>XRPリアルタイム貸出レート一覧(年利)</h4>Celsius : 5.1%<br>";
lend("XRP");
}elseif($_POST['tuka']=="BTC"){
echo "<h4>BTCリアルタイム貸出レート一覧(年利)</h4>Celsius : 4.1%<br>";
lend("BTC");
}elseif($_POST['tuka']=="ETH"){
echo "<h4>ETHリアルタイム貸出レート一覧(年利)</h4>Celsius : 4.55%<br>";
lend("ETH");
}elseif($_POST['tuka']=="LTC"){
echo "<h4>LTCリアルタイム貸出レート一覧(年利)</h4>Celsius : 6.15%<br>";
lend("LTC");
}
else{
echo "通貨を選択してください。";
}
echo "<br>更新:".date("Y/m/d H:i:s");
?>

コメント

  1. Hiroaki より:

    管理人バカルダー様

    初めまして、Hiroakiと申します!
    自分も現在WPにてホームページを作成しており、こちらのページを読ませて頂き大変参考になりました!ありがとうございます。
    私はcocoonを使っていないため、どこにJavaScript書けばいいんだ…と迷走しましたw

    ご教示いただけると幸いなのですが、phpファイル上でインストールしているプラグインのショートコードは呼び出せるものなのでしょうか?
    php文内で<?php echo do_shortcode で呼び出しているためか全くうまくいかず…汗

    厚かましいお願いではございますが、ご教示頂けると大変助かります。

    • コメントありがとうございます!javascriptは</body>の直前の書けば大丈夫だと思います!

      ショートコードについては私も色々再現しようと試してみましたが出来ませんでした・・・

      ショートコードはテーマファイル内のみでしか作動しないと思いますので、wpフォルダ直下のphpファイルに記述しても動かないと思います。

      なので、こちらの「WordPressのページ間でPOSTデータを送受信する」を応用したらできるかもしれません。

      私ももう少しいろいろ試してみますが、Hiroakiさんの方で解決策が見つかりましたらまたコメント頂けると助かります。

  2. Hiroaki より:

    管理人バカルダー様

    返信ありがとうございます!
    カスタムJavaScript導入はfuction.phpにカスタムを導入するコードを入れたのですが、
    紹介しているサイトでも自分のと合う・合わないがあって大変でした…
    (ただ仕組み理解してない&勉強不足なのですが汗)

    >ショートコードはテーマファイル内のみでしか作動しない~
    php内でショートコードを呼び出そうとすると未定義の関数呼び出しでエラーになりました。
    何かしらテーマファイル外からの呼び出しを定義すればいけるのですかね?
    今、funciton.phpに再定義して呼び出せないか悪あがき中ですw
    万が一出来ましたらご報告あげます~^^

    • そうなんですね~私もエンジニアとかではなく独学でやってるのであまりお力になれず申し訳ないです((+_+))

      私もいろいろ挑戦してみます!ご報告楽しみにしてます!