Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【jQuery】PHP/Ajax/MySQL を利用した非同期通信を行う

More than 1 year has passed since last update.

実装内容

  • productsテーブルを作成する。(カラムはid, name, priceの3つ)
  • 一覧に常にレコード全件が表示される
  • 特定のidからnameとpriceを取り出して表示する
  • 新しくレコードを追加して、一覧に追記する
  • レコード追加前に確認メッセージを表示する

AjaxとJSON

こちらの記事がわかりやすいです!

初心者目線でAjaxの説明

Ajax

  • Asynchronous JavaScript + XML
  • JavaScript組み込みクラスであるXMLHttpRequestによる非同期(Asynchronous)通信のこと

JSON

  • JavaScript Object Notation
  • データ形式の1つ
  • XMLに替わり、Ajaxで使われることが多い

ファイル構成

サーバはApache、データベースはMySQLを使用しました。

htdocsの下にajax_testディレクトリを用意し、その中に必要なファイルを作成します。

$ pwd
/usr/local/var/www/htdocs/ajax_test
$ ls
ajax_test.html      ajax_test_add.php   ajax_test_show_all.php
ajax_test.js        ajax_test_show.php

テーブルの作成

既存のデータベースdb1にproductsテーブルを追加しました。

作成済みのテーブルは、SHOW CREATE TABLEコマンドで作成時のクエリを確認できるので便利です。

Tableカラムにテーブル名、Create Tableカラムに作成時のクエリが表示されます。(ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8は、テーブル作成時には記述していません。)

mysql> use db1;
SHOW CREATE TABLE products;

Create Tableの値

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8

適当にレコードを作成しておきます。

mysql> INSERT INTO products(name, price) VALUES('りんご', 100), ('みかん', 80);

ちなみに、MySQLのコマンドラインは\cで入力キャンセルができます。(前までは\qを実行していて、コマンドラインから退出してました;)

MySQLのコマンドラインで入力をキャンセルする

HTML

ajax_test.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <!-- jQueryの読み込み -->
    <title>Ajax、PHP、MySQLの連携</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <!-- 指定したidからレコード取得 -->
    <div class="show_products">
        IDを入力:<input id="id_number"><br>
        <!-- 取得したレコードを表示 -->
        <div id="result">
        </div>
        <!-- 送信ボタン -->
        <button id="ajax_show">詳細ボタン</button>
    </div>
    <!-- レコード追加 -->
    <div class="add_products">
        <!-- 入力フォーム -->
        商品名を入力:<input id="name"><br>
        価格を入力:<input id="price"><br>
        <!-- レコード追加後に入力内容を表示 -->
        <div id="add_result">
        </div>
        <!-- 送信ボタン -->
        <button id="ajax_add">追加ボタン</button>
    </div>
    <!-- レコード全件取得 -->
    <!-- 追加したレコードも即時反映される -->
    <table border="1" id="all_show_result">
        <tr>
            <th>id</th><th>商品名</th><th>価格</th>
        </tr>
    </table>
    <script src="ajax_test.js"></script>
</body>
</html>

jQuery

勉強用なので、やたらとconsole.logが記述してあります。

ajax_test.js
$(function(){
// レコードを全件表示する
// 試しに関数にしてみただけ
function getAllData(){
    $.ajax({
        // 通信先ファイル名
        url: "ajax_test_show_all.php",
        // 通信が成功した時
        success: function(data) {
            // 取得したレコードをeachで順次取り出す
            $.each(data, function(key, value){
                // #all_show_result内にappendで追記していく
                $('#all_show_result').append("<tr><td>" + value.id + "</td><td>" + value.name + "</td><td>" + value.price + "</td></tr>");
            });

            console.log("通信失敗");
            console.log(data);
        },

        // 通信が失敗した時
        error: function(){
            console.log("通信失敗");
            console.log(data);
        }
    });
}

// 関数を実行
getAllData();

// #ajax_showがクリックされた時の処理
// 指定したidのレコードを取得する
$('#ajax_show').on('click',function(){
    $.ajax({
        // リクエスト方法
        type: "GET",
        // 送信先ファイル名
        url: "ajax_test_show.php",
        // 受け取りデータの種類
        datatype: "json",
        // 送信データ
        data:{
            // #id_numberのvalueをセット
            "id" : $('#id_number').val()
        },
        // 通信が成功した時
        success: function(data) {
            // 取得件数が1件のため、取得した情報を#result内にそのまま追加する
            $('#result').html("<p>ID番号" + data[0].id + "は「" + data[0].name + "」です。<br>価格は「" + data[0].price+"円」です。</p>");

            console.log("通信成功");
            console.log(data);
        },

        // 通信が失敗した時
        error: function(data) {
            console.log("通信失敗");
            console.log(data);
        }
    });

    return false;
});

// #ajax_addがクリックされた時の処理
$('#ajax_add').on('click',function(){
    // 確認メッセージを表示
    // OKならtrue,キャンセルならfalseが代入される
    var confirmResult = window.confirm("登録してもよろしいですか?");

    if(confirmResult) {
        $.ajax({
            // 送信方法
            type: "POST",
            // 送信先ファイル名
            url: "ajax_test_add.php",
            // 受け取りデータの種類
            datatype: "json",
            // 送信データ
            data: {
                // #nameと#priceのvalueをセット
                "name" : $('#name').val(),
                "price" : $('#price').val()
            },
            // 通信が成功した時
            success: function(data) {
                $('#add_result').html("<p>" + data[0].name + "" + data[0].price + "円のデータを登録しました。</p>");

                console.log("通信成功");
                console.log(data);

                // 一覧に追加したレコードを追記
                $.each(data, function(key, value){
                    $('#all_show_result').append("<tr><td>" + value.id + "</td><td>" + value.name + "</td><td>" + value.price + "</td></tr>");
                });
            },

            // 通信が失敗した時
            error: function(data) {
                console.log("通信失敗");
                console.log(data);
            }
        });
    }

    return false;
});
});

こんな書き方も

getメソッド

通信の成功時のみ、実行されます。

ajax_test.js
function getAllData(){
    $.get("ajax_test_show_all.php",
        function(data){
            $.each(data, function(key, value){
                $('#all_show_result').append("<tr><td>" + value.id + "</td><td>" + value.name + "</td><td>" + value.price + "</td></tr>");
            });

            console.log("通信成功");
            console.log(data);
        }
    );
}

doneメソッドとfailメソッド

メソッドチェーンを使います。

ajax_test.js
$('#ajax_show').on('click',function(){
    $.ajax({
        // リクエスト方法
        type: "GET",
        // 送信先ファイル名
        url: "ajax_test_show.php",
        // 受け取りデータの種類
        datatype: "json",
        // 送信データ
        data:{
            // #id_numberのvalueをセット
            "id" : $('#id_number').val()
        }
    })

    // 通信が成功した時
    .done( function(data) {
        $('#result').html("<p>ID番号" + data[0].id + "は「" + data[0].name + "」です。<br>価格は「" + data[0].price+"円」です。</p>");

        console.log('通信成功');
        console.log(data);
    })

    // 通信が失敗した時
    .fail( function(data) {
        console.log('通信失敗');
        console.log(data);
    });

    return false;
});

レコード表示処理(全件)

コードの重複が多い・・・

ajax_test_show_all.php
<?php
// データベース接続
// $host = localhostで動かなければipアドレスを記載
$host = '127.0.0.1';
// データベース名
$dbname = 'db1';
// ユーザー名
$dbuser = 'user_name';
// パスワード
$dbpass = 'password';

// データベース接続クラスPDOのインスタンス$dbhを作成する
try {
    $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
// PDOExceptionクラスのインスタンス$eからエラーメッセージを取得
} catch (PDOException $e) {
    // 接続できなかったらvar_dumpの後に処理を終了する
    var_dump($e->getMessage());
    exit;
}

// データ取得用SQL
// 値はバインドさせる
$sql = "SELECT id, name, price FROM products";
// SQLをセット
$stmt = $dbh->prepare($sql);
// SQLを実行
$stmt->execute();

// あらかじめ配列$productListを作成する
// 受け取ったデータを配列に代入する
// 最終的にhtmlへ渡される
$productList = array();

// fetchメソッドでSQLの結果を取得
// 定数をPDO::FETCH_ASSOC:に指定すると連想配列で結果を取得できる
// 取得したデータを$productListへ代入する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    $productList[] = array(
        'id'    => $row['id'],
        'name'  => $row['name'],
        'price' => $row['price']
    );
}

// ヘッダーを指定することによりjsonの動作を安定させる
header('Content-type: application/json');
// htmlへ渡す配列$productListをjsonに変換する
echo json_encode($productList);

レコード表示処理(id検索の1件のみ)

ajax_test_show.php
<?php
// GETメソッドでリクエストした値を取得
$id = $_GET['id'];

// データベース接続
// $host = localhostで動かなければipアドレスを記載
$host = '127.0.0.1';
// データベース名
$dbname = 'db1';
// ユーザー名
$dbuser = 'user_name';
// パスワード
$dbpass = 'password';

// データベース接続クラスPDOのインスタンス$dbhを作成する
try {
    $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
// PDOExceptionクラスのインスタンス$eからエラーメッセージを取得
} catch (PDOException $e) {
    // 接続できなかったらvar_dumpの後に処理を終了する
    var_dump($e->getMessage());
    exit;
}

// データ取得用SQL
// 値はバインドさせる
$sql = "SELECT id, name, price FROM products WHERE id = ?";
// SQLをセット
$stmt = $dbh->prepare($sql);
// SQLを実行
$stmt->execute(array($id));

// あらかじめ配列$productListを作成する
// 受け取ったデータを配列に代入する
// 最終的にhtmlへ渡される
$productList = array();

// fetchメソッドでSQLの結果を取得
// 定数をPDO::FETCH_ASSOC:に指定すると連想配列で結果を取得できる
// 取得したデータを$productListへ代入する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    $productList[] = array(
        'id'    => $row['id'],
        'name'  => $row['name'],
        'price' => $row['price']
    );
}

// ヘッダーを指定することによりjsonの動作を安定させる
header('Content-type: application/json');
// htmlへ渡す配列$productListをjsonに変換する
echo json_encode($productList);

リクエストメソッドはGETを使用しているので、http://localhost/ajax_test/ajax_test_show.php/?id=41/でアクセスすると、[{"id":41,"name":"\u308a\u3093\u3054","price":100}]のようにレスポンスが返ってきます。

データ形式はもちろんJSONです。

レコード追加処理

ajax_test_add.php
<?php
// POSTメソッドでリクエストした値を取得
$name = $_POST['name'];
$price = $_POST['price'];

// データベース接続
// $host = localhostで動かなければipアドレスを記載
$host = '127.0.0.1';
// データベース名
$dbname = 'db1';
// ユーザー名
$dbuser = 'user_name';
// パスワード
$dbpass = 'password';

// データベース接続クラスPDOのインスタンス$dbhを作成する
try {
    $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
// PDOExceptionクラスのインスタンス$eからエラーメッセージを取得
} catch (PDOException $e) {
    // 接続できなかったらvar_dumpの後に処理を終了する
    var_dump($e->getMessage());
    exit;
}

// データ追加用SQL
// 値はバインドさせる
$sql = "INSERT INTO products(name, price) VALUES(?, ?)";
// SQLをセット
$stmt = $dbh->prepare($sql);
// SQLを実行
$stmt->execute(array($name, $price));

// 先ほど追加したデータを取得
// idはlastInsertId()で取得できる
$last_id = $dbh->lastInsertId();
// データ追加用SQL
// 値はバインドさせる
$sql = "SELECT id, name, price FROM products WHERE id = ?";
// SQLをセット
$stmt = ($dbh->prepare($sql));
// SQLを実行
$stmt->execute(array($last_id));

// あらかじめ配列$productListを作成する
// 受け取ったデータを配列に代入する
// 最終的にhtmlへ渡される
$productList = array();

// fetchメソッドでSQLの結果を取得
// 定数をPDO::FETCH_ASSOC:に指定すると連想配列で結果を取得できる
// 取得したデータを$productListへ代入する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    $productList[] = array(
        'id'    => $row['id'],
        'name'  => $row['name'],
        'price' => $row['price']
    );
}

// ヘッダーを指定することによりjsonの動作を安定させる
header('Content-type: application/json');
// htmlへ渡す配列$productListをjsonに変換する
echo json_encode($productList);

追加したばかりのレコードのidがどのように渡されているか、var_dump(array($last_id));を追記して確認できます。(内容はデベロッパーツールで確認できます。)

こんな感じで返ってきます。

ajax_test_add.php
array(1) {
  [0]=>
  string(2) "61"
}

参考記事

Ajaxを使ってデータベースのデータを非同期で取得する【Ajax+MySQL+PHP】

yukibe
2018年8月よりWebエンジニア。主にPHP。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away