PHP-DB - 13. SELECT文の実行

続いてプリペアドステートメントを使って select 文を実行する方法を見ていきましょう。次のプログラム( pdo11.php )を作成します。

<?php
try {
    $dsn = "mysql:host=localhost;dbname=eldb;charset=utf8mb4";
    $username = "root";
    $password = "admin";
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "select * from categories where title = ?";
    $ps = $pdo->prepare($sql);

    $title = 'Photo';
    $ps->bindValue(1, $title, PDO::PARAM_STR);

    $ps->execute();

    $rows = $ps->fetchAll();
    var_dump($rows);
} catch (PDOException $e) {
    echo $e->getMessage() . PHP_EOL;
}

select 文を実行する場合も大きな処理の流れは変わりません。まずはプレースホルダを利用したSQL文字列を定義して、 PDO クラスの prepare メソッドを呼び出し、 PDOStatement インスタンスを取得します。

    $sql = "select * from categories where title = ?";
    $ps = $pdo->prepare($sql);

次に PDOStatement クラスの bindValue メソッドを使ってプレースホルダにデータをバインドします。

    $title = 'Photo';
    $ps->bindValue(1, $title, PDO::PARAM_STR);

このプログラムではプレースホルダは1つだけしか使っていないので bindValue メソッドの呼び出しは1回だけで済みます。

プレースホルダにデータをバインドできたので PDOStatement クラスの execute メソッドを呼び出して解析済みのSQLを実行します。

    $ps->execute();

さいごに select 文を実行した場合はデータをフェッチする必要があります。ここでは PDOStatement クラスの fetchAll メソッドを呼び出します。

    $rows = $ps->fetchAll();

それではターミナルからプログラムを実行してみましょう。

$ php pdo11.php
array(1) {
  [0]=>
  array(4) {
    ["id"]=>
    int(4)
    [0]=>
    int(4)
    ["title"]=>
    string(5) "Photo"
    [1]=>
    string(5) "Photo"
  }
}

実行結果からプリペアドステートメントを使用して select 文を実行できている様子を確認できます。

executeメソッドによるデータバインド

これまでに学習してきたとおり、プリペアドステートメントではSQLにプレースホルダを利用できます。プレースホルダにデータをバインドするには PDOStatemen クラスの bindValue メソッドを使用してきましたが、次のように execute メソッドに引数を指定して、プレースホルダへのデータバインドと実行処理をまとめて行うことも可能です。

<?php
try {
    $dsn = "mysql:host=localhost;dbname=eldb;charset=utf8mb4";
    $username = "root";
    $password = "admin";
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "select * from categories where title = ?";
    $ps = $pdo->prepare($sql);

    $ps->execute(['Photo']);

    $rows = $ps->fetchAll();
    var_dump($rows);
} catch (PDOException $e) {
    echo $e->getMessage() . PHP_EOL;
}

ここでは PDOStatement クラスの execute メソッドを以下のように呼び出しています。

    $ps->execute(['Photo']);

execute メソッドは引数に配列を受け取ることが可能です。このように引数に配列を指定すると、配列の先頭要素から順にプレースホルダにバインドされるようになっています。

それではターミナルからプログラムを実行してみましょう。

$ php pdo11.php
array(1) {
  [0]=>
  array(4) {
    ["id"]=>
    int(4)
    [0]=>
    int(4)
    ["title"]=>
    string(5) "Photo"
    [1]=>
    string(5) "Photo"
  }
}

実行結果から前回と同様にSQLを処理できているのがわかります。

まとめ

  • select 文の場合も同様にプリペアドステートメントを利用できる
  • prepare メソッドによる構文解析、 bindValue によるパラメータの設定、 execute メソッドによる解析済みのSQLの実行は同じ
  • select 文の実行時は execute メソッドを呼び出した後に fetchfetchAll メソッドを呼び出して結果にアクセスする