PHP Data Object
DBからデータ引っ張り出せればあとはなんとかなるんじゃなかろうかという期待の元、とにかくまずはPHPでデータベース操作するやり方を調べる。そのうちPDOっていうやつを見つけた。やってみましょう。
DBに接続する
接続情報は別にサーバー外から見れるわけではないっぽいんだけど、なんかこうぃので外部ファイルに移しとく。
<?php
$dsn = 'dsn:host=localhost;dbname=shogi';
$user = '****';
$password = '******';
?>
でshogi_config.phpに保存。そんでメインの方でrequireで引っ張る。で、色々書いて
<?php
require ('shogi_config.php');
try {
$pdo = new PDO($dsn, $user, $password);
print ('接続しました。');
} catch (PDOException $ext) {
die('接続してない。'.$ext->getMessage());
}
$pdo = null;
?>
うむ。最初requireの後に;入れるの忘れてて、syntax error, unexpected ‘try’ (T_TRY)っていうエラーが出ておった。まぁそれはそれとして。この状態でサーバーにアップしてみたら、接続しました。って表示された。幸先がよろしい。
SQLを発行する
とりま変数とか使わずにべた書きする。
$sql = "SELECT * FROM data WHERE id=1234";
$state = $pdo->query($sql);
$res = $state->fetch(PDO::FETCH_NUM);
foreach ($res as $r => $v) {
print($v."\n");
}
て書く。query投げて戻り値をfetchしてprint。
結果
文字化けしとるなー。また文字コードがどうたらかな。config.phpの$dsnに
charset=utf8
を追加したら直った!じゃあレコードが複数ある場合はどうすんの?と試してみる。sqlを
$sql = "SELECT * FROM data WHERE id IN (1234, 1235)";
てしてみたけど、1234の方しか表示されない。で、色々試してみたら
$sql = "SELECT * FROM data WHERE id IN (1234, 1235)";
$state = $pdo->query($sql);
$res = $state->fetch(PDO::FETCH_ASSOC);
foreach ($res as $r => $v) {
print($v."\n<br>");
}
$res = $state->fetch(PDO::FETCH_ASSOC);
foreach ($res as $r => $v) {
print($v."\n<br>");
}
っつって、fetchを2回やってみたらどっちも表示された。
うーん、なんかあんまコードがキレイじゃないね。どうやるのがいいんだろうなぁ。まぁそれは置いといて、変数使うやつやる。
プレースホルダー
外部入力をまんまSQL文につないで発行したりすると、悪意を持った攻撃者に悪いことされる。SQLインジェクションってやつだ!基本情報で出てきたなぁ。でそれを防ぐためにプレースホルダーを使いましょう、ということみたい。SQL文のテンプレートを作っておいて、プリペアードステートメントを介して値を設定するみたいな流れらしい。この前作ったDBを検索したいってなると、日付、作成者、手数で絞るような使い方になるのかなーって思う。それ用にSQLのテンプレートを作れるだろか。
$sql = <<<EOD
SELECT * FROM data
WHERE date BETWEEN :date_from AND :date_to
AND maker = :maker
AND steps = :steps
EOD;
$df = '2020-08-01';
$dt = '2020-08-15';
$maker = '';
$steps = 3;
$state = $pdo->prepare($sql);
$state->bindValue(':date_from',$df);
$state->bindValue(':date_to',$dt);
$state->bindValue(':maker',$maker);
$state->bindValue(':steps',$steps);
$state->execute();
$res = $state->fetchAll(PDO::FETCH_ASSOC);
var_dump($res);
こんな感じかな…。これ例えばmakerはワイルドカードでいい、みたいな時ってどうすればいいんだろうな~。
実行するとこんな。ちゃんと取得できてるっぽい。そしたら、んー、フォームを作ってみようかな?