実装内容
- productsテーブルを作成する。(カラムはid, name, priceの3つ)
- 一覧に常にレコード全件が表示される
- 特定のidからnameとpriceを取り出して表示する
- 新しくレコードを追加して、一覧に追記する
- レコード追加前に確認メッセージを表示する
AjaxとJSON
こちらの記事がわかりやすいです!
##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
を実行していて、コマンドラインから退出してました;)
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が記述してあります。
$(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メソッド
通信の成功時のみ、実行されます。
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_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;
});
レコード表示処理(全件)
コードの重複が多い・・・
<?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件のみ)
<?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です。
レコード追加処理
<?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));
を追記して確認できます。(内容はデベロッパーツールで確認できます。)
こんな感じで返ってきます。
array(1) {
[0]=>
string(2) "61"
}