3、 PHPを使ったMySQLへのアクセスとクエリ設定
PHPのビルトイン関数を使ってMySQLにアクセスし、SQLの結果をファイルに保存する
プログラム作成の手順は以下のとおり。
1) MySQLに接続しログイン
2) 使用するデータベースを選択
3) クエリストリングを作成
4) クエリの実行
5) 結果を取得し、ファイルに保存
6) MySQLの接続解除
3−1、 PDOと利用環境の設定について
PDO(PHP Data Object)とは、PHP標準(5.1.0以降)のデータベース接続クラスのこと。
PHPは標準でMySQLやPostgreSQLやSQLiteなど、色々なデータベースに接続するための命令が用意されているが、PDOを使用すると同じ命令で複数のデータベースに接続ができるようになるので、PDOをによる開発が主流になっている。(参考:PHP Labo)
そこで、PDOを利用してECLIPSEで開発しようとしたところ、mysqliが呼べない。phpinfo()でmysqldの項目を確認すると、API Extensionにmysqli、pdo-mysqlが表示されていない。
ネット検索をすると、Windowsの環境でPDOを利用する場合、まず「php.ini」への設定が必要とのこと。
具体的には「php.ini」の DLLを設定する部分で
・MySQLを利用する場合は「extension=php_mysql.dll」
・PDOを利用する場合は「extension=php_pdo.dll」
の先頭のセミコロン(;)を削除し有効にしろとのこと。(参考:PHPの設定)
そこでLinuxでも同様であろうと考え、etc/php/7.2/apache2/php.initの901行目と906行目のextensionのセミコロンを削除して保存したところ動作した。 (php.iniの整合をとるため、後日/etc/php/7.2/cli/php.iniにも同様の変更を行ったところ動作しなくなり、もとに戻した。)
php.ini ;extension=mbstring ;extension=exif ; Must be after mbstring as it depends on it extension=mysqli ;extension=oci8_12c ; Use with Oracle Database 12c Instant Client ;extension=odbc ;extension=openssl ;extension=pdo_firebird extension=pdo_mysql ;extension=pdo_oci ;extension=pdo_odbc ;extension=pdo_pgsql ;extension=pdo_sqlite
3−2、PDOを使ってデータベースから検索データを抽出しクライアントフォルダ(ローカルフオルダ)にファイル出力させる
PHPマニュアル,、「PHP Labo」、「基礎:PHPでDBからCSVを出力する」の記事を参考にProgramを作成。
1)loginファイルの作成
データベースに接続するための単一のphpプログラムを作成し、検索を実行するPHPプログラム内で、require_onceステートメントを使って読み込むようにする。
// login-PDO.php
$host = 'localhost'; // hostname
$data = 'climate'; // use datbase name
$user = 'miyasan'; // username
$pass = '********'; // password
$chrs = 'utf8mb4';
$attr = "mysql:host=$host;dbname=$data;charset=$chrs";
// PDOのオプション設定
//setAttributeメソッドは、属性をセットするメソッド
//オプションが複数になる場合は、$options変数などを用意して、
//その$options変数をPDOインスタンス生成時に、第4引数として渡してやると良い
$opts =
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //PDOの例外エラーを詳細にしてくれるオプション
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //select文やwhere句などの結果を連想配列として返してくれるようになる
PDO::ATTR_EMULATE_PREPARES => false, //
];
2)データベースに接続する
データベースに接続するにはPDO クラスを使用。接続に成功するとオブジェクトが返される。
オブジェクト = new PDO( 'データベースの種類:dbname=データベース名;host=接続先アドレス', 'ユーザー名', 'パスワード' );
接続に失敗するとPDOは「例外」を発生させる。これは try と catch を使用すれば補足することができる。
例外処理する構文:
try { $pdo = new PDO($attr, $user, $pass, $opts); echo "データベース接続OK\n"." "; } catch (\PDOException $e) //PDOException:PDOが発するエラーを表します { //例外を知らせることを例外を投げるという(throw)。 throw new \PDOException($e->getMessage(), (int)$e->getCode()); }
3) SQL文を実行し、抽出結果をCSVファイルに出力する
// filename:agri.php
// login情報ファイル読み込み
require_once 'login-PDO.php';
// データベースに接続する。
try
{
$pdo = new PDO($attr, $user, $pass, $opts);
echo "データベース接続OK\n"."
";
}
catch (\PDOException $e) //PDOException:PDOが発するエラーを表します
{
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
// CSVのファイルパス名・ヘッダー名を定義
$file_path = "/home/miyasan/agri.csv"; //ファイル名
//SQL文 //////////////////////////////////
$export_sql = "SELECT * FROM iida_agri_sensor
WHERE date BETWEEN '2020-07-02' AND '2020-07-04'";
/* Queryがうまくいったかコンソールで確認する際はコメントアウトを外す
$result = $pdo->query($export_sql);
while ($row = $result->fetch())
{
echo 'date: ' . htmlspecialchars($row['date']) . "<br>";
echo 'temp: ' . htmlspecialchars($row['temp']) . "<br>";
echo 'humid: ' . htmlspecialchars($row['humid']) . "<br>";
echo 'press: ' . htmlspecialchars($row['press']) . "<br>";
}
*/
// CSVファイルに書き込み出力
// 参考:https://qiita.com/hgsgtk/items/7782e81ccee8386bbc0b
if(touch($file_path)){
$file = new SplFileObject($file_path, "w");
// データベース検索
$stmt = $pdo->query($export_sql);
// 検索結果をCSVに書き込む
// 引数のPDO::FETCH_ASSOCは、列名を記述し配列で取り出す設定をしている。配列の最後まで下記を実行し続ける
// fetch:取り出す。Assoc:Associationで、連想する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$file->fputcsv($row);
}
// データベース接続の切断
$pdo = null;
}
3−3、 コマンドラインから検索期間を引数で与える場合のスクリプト
> php pdo_arg.php 2020-07-01 2020-07-07
//SQL文
$yymm1 = $argv[1];
$yymm2 = $argv[2];
//引数を使った検索用のSELECT文は以下のように通常のDATE入力と同様、変数を''で囲めばOK
$export_sql = "SELECT * FROM iida_agri_sensor WHERE date BETWEEN '$yymm1' AND '$yymm2'";
このとき、引数を''付きのテキストとして入力してもPHPがSTRINGとして判断してくれる。
$ php pdo_arg.php '2020-07-01' '2020-07-03'
3−4、 プリペアードステートメント
クエリを強制的に改ざんさせられるようなSQLインジェクション攻撃の対策方法として、プレースホルダ機能を使った検索が一般的。これはクエリを直接呼び出す代わりに、データが来る場所に :
に続けて半角英数字でキーワードをおいたり、「?」文字を使ってあらかじめクエリを定義し、クエリを呼び出すときにデータを渡す方法。
// SQL文 prepared statementでクエリデータを受け渡す
$export_sql = "SELECT * FROM iida_agri_sensor WHERE date BETWEEN :date1 AND :date2";
// prepareでSQL文をセット
$stmt = $pdo -> prepare($export_sql);
// bindValueで値をセット :date1,:date2を変数値に置き換える
$stmt -> bindValue(':date1', $yymm1);
$stmt -> bindValue(':date2', $yymm2);
// CSV書き込み出力
if(touch($file_path)){
$file = new SplFileObject($file_path, "w");
//executeで実行
$stmt->execute();
// 引数のPDO::FETCH_ASSOCは、列名を記述し配列で取り出す設定をしている。配列の最後まで下記を実行し続ける
// fetch:取り出す。Assoc:Associationで、連想する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$file->fputcsv($row);
}
// データベース接続の切断
$pdo = null;
PHP・MySQL・canvasJSを使った動的なチャート生成 関連記事
4、 Pythonを使ったMySQLへのアクセスとクエリ設定
コメント