php + ajax でDBからデータを取得・出力するためのちょっとした話


概要

案件で、2000ぐらいのファイルをそれぞれダウンロードするサイトを制作しました。
クライアントからDB仕様指示はないので、静的htmlで制作することも可でしたが、量が多すぎるのでDBを使用にすることに至りました。
DBを使った案件は初めてで(WPを除く)、PHPもWPのテーマ作成ぐらいしか実戦経験がなかったので、キツかった。。。
振り返りを兼ねての自分メモで。
DBはMySQLでphpMyAdminを使用しています。

仕様

目的:
製品サイト内にて、製品の資料ファイルをダウンロードする。サイト自体は1ページです。
サイトを上下に2分割した際に、上に製品カテゴリのナビがあり、選択したカテゴリのダウンロードリンクを搭載した下にテーブルが表示される。
上で選択したアイテムをパラメータとして渡すことで、下のテーブルをajaxで動的に出力します。

Ajax

「エイジャックス」派です。
基本的な書き方はこんな感じでしょうか。

ajax.js
$(function() {
 $('.btn').on('click', function() {
  $.ajax({
   url: ('path/to/file.php'), // ajax通信をするファイル
   type: 'GET', // GET or POST
   data: { f: $(this).value(); }, // パラメータとして渡す値の指定
   dataType: 'html', // 今回は直接htmlを出力したかったのでhtml。受け取ったデータで更に処理したい場合はjson
   cache: true, // 通信のキャッシュを残すか
   // ajax通信成功
   success: function(data) {
  // 引数でデータを受け取り
    $('#content').html(data);
   },
   // ajax通信失敗
   error: function() {
    console.log('fail');
   }
  });
 });
});

コードの意図としては、ボタンをクリックした際にajax通信を行う。押したボタンbuttonvalueを取得しパラメータfとしてpath/to/file.phpに渡します。
一連の流れが成功すれば、#contenthtmlを出力します。ボタンを押すたびにhtmlを動的に書き換えることができます。
dataの取得方法がよくわからず苦戦しました。他にフォームであれば、inputの値などを指定します。

ちなみにナウい書き方だとこんな感じ

ajax_new.js
$(function() {
 $('.btn').on('click', function() {
  $.ajax({
   // options 略
  }).then(
   function(data) {
    // success
    console.log(data)
   },
   function() {
    // fail 
    console.log('error');
   }
  );
 });
});

PHP

ajax通信時の設定を行う。

connect.php
// DB settings
$host = 'localhost';
$dbname = 'dbname';
$dbusr = 'dbusr';
$dbpass = 'dbpass';

//↑ settingsからDBに接続する
try {
  // 成功
  $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
} catch (PDOException $e) {
  // 失敗
  var_dump('データベース接続失敗' . $e->getMessage());
  exit;
}

// SQL実行準備
$stmt = $dbh->prepare("SELECT * FROM table");
// SQL実行
$stmt->execute();

// 受け取りデータを配列に格納
$dataList = array();

// あらかじめ作成した配列にwhuileで格納する
// FETCH_ASSOCで連想配列化する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
  $productList[] = array(
   'id' => $row['id'];
   'name' => $row['name'];
  );
}

// XSS対策
function hsc($str){
  return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// htmlをそのままechoするので以下指定。Content-typeは適宜変更
header('Content-type:text/plain; charset=utf8');

// urlパラメータ「p」のGETが実行されているか
if (isset($_GET['p'])) {
 // パラメータを受け取ったら変数化  
 $format = $_GET['p'];

 // ここでhtml出力します
 echo '通信成功です!';
}

ひとまず完成して動いたので、営業にテストアップ報告を行ったのですが
まだまだわからないことが多い。。。