ホームページをリニューアルしました。旧HPはこちら
MySQL ソフト・ハードウェア PHP

PHP・MySQL・canvasJSを使った動的なチャート生成(その3)

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を使った動的なチャート生成 関連記事

1、 ローカルサーバの開発環境の設定

2、 MySQLに気象観測データベースを作成

3、 PHPを使ったMySQLへのアクセスとクエリ設定

4、 Pythonを使ったMySQLへのアクセスとクエリ設定

5、 フォームからの送信データ取得と表示・ファイル保存

6、 MySQLデータを用いcanvasによるチャート作成

 

 

コメント

タイトルとURLをコピーしました