PDOでSELECTの使い方【PHP】

PDOのSELECT文でデータを取得する方法についてまとめました。

例で出すサンプルコードで使用するテーブルは、下記のものを使用します。

table名:yasai_item
id name price
1 にんじん 50
2 トマト 100
3 きゅうり 80

PDOでのSELECT文の実行方法

SELECT文に限らず、PDOでSQL文を実行する方法は大きく分けて2つあります。

  • query
  • prepare→execute

queryとprepareを使用したSELECT文の実行方法をそれぞれで解説していきます。

query

queryは、既にSQL文が確定されたクエリを使用する場合に主に使用します。

サンプルコード
//SQL文 80円以上の野菜のみ取得
$sql = "SELECT * 
        FROM yasai_item 
        WHERE price >= 80";

//queryで実行 結果セットを$sthに代入
$sth = $pdo -> query($sql);

//結果セットから配列を取得
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC);

print_r($aryItem);
Array
(
    [0] => Array
        (
            [id] => 2
            [name] => トマト
            [price] => 100
        )

    [1] => Array
        (
            [id] => 3
            [name] => きゅうり
            [price] => 80
        )

)

SQL文自体が不変な場合などによく使用します。

もちろん、$sql変数に文字列連結して、変数を組み込むことも可能です。

//SQL文 80円以上の野菜のみ取得
$price = 80;
$sql = "SELECT * 
        FROM yasai_item 
        WHERE price >= ".$price;

ただし、この場合に文字列連結で組み込む変数は、外部のユーザーから取得した値を何の検証もせずに組み込むと、SQLインジェクション攻撃を受ける可能性があります。

//やってはいけない例 $_GETなどでユーザーから入力された値を文字列連結で組み込む
$sql = "SELECT * 
        FROM yasai_item 
        WHERE price >= ".$_GET['price'];

参考 PHPでSQLインジェクション攻撃の対策方法【PDO】

繰り返しますが、文字列連結で変数を使用する場合は、変数が安全なことを保証されている場合に限ります。

不特定多数のユーザーから受け取った値を、SQL文に組み込みたい場合は、後述のprepareを使用してください。

prepare→execute

prepareは、SQL文の実行を準備して、その後にクエリに値をセットして実行できる機能です。

参考 PDOでprepareの使い方【PHP】

prepareを使用することで、同じSQL文を値だけ変えて使いまわしたり、クエリを強制的に改ざんさせられるSQLインジェクション攻撃の対策が可能です。

サンプルコード
$price = 80;

//SQL文 80円以上の野菜のみ取得
$sql = "SELECT * 
        FROM yasai_item 
        WHERE price >= :price";

//prepareでSQL文をセット
$sth = $pdo -> prepare($sql);

//bindValueで値をセット :priceを値に置き換える
$sth -> bindValue(':price', $price);
//$sth -> bindValue(':price', 80); と直接値を入力しても良い

//executeで実行
$sth -> execute();

//結果セットから配列を取得
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC);

print_r($aryItem);
Array
(
    [0] => Array
        (
            [id] => 2
            [name] => トマト
            [price] => 100
        )

    [1] => Array
        (
            [id] => 3
            [name] => きゅうり
            [price] => 80
        )

)

prepareの実行は、下記の流れで行います。

  • prepare()でクエリの実行準備
  • bindValue()でクエリ内の値を設定
  • execute()でクエリの実行
  • fetch()などでデータの取得

値の代入をする方法をいくつかありますが、「:(コロン)」と「任意の名前」を付けてbindValueでセットする方法が便利です。
上述の例では「:price」と名付けました。

また、prepareで一度SQL文を確定させているため、例えば「:price」はpriceとの比較でしか使用されない変数となります。
このため、SQLインジェクションのように無理やり違ったクエリを実行されることがなく、セキュリティ面でも安全に実行が出来ます。

ちなみに、値をセットしなくても実行できるため、queryのように使用することも可能です。

//実行可能
$sql = "SELECT * 
        FROM yasai_item 
        WHERE price >= 80";
$sth = $pdo -> prepare($sql);
$sth -> execute();
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC);

SELECTの結果をfetch、fetchAllで取得する

SELECT文の実行結果を配列で取得するには、fetch、もしくはfetchAllといったメソッドを使用します。

結果セットを取得する

fetch系のメソッドは、「結果セット」と呼ばれる変数(クラス)から使用します。
そのため、実行結果をqueryまたはexecute時に変数に代入する必要があります。

今回は$sthという変数を使用するものとして解説します。

//queryの場合
$sql = "SELECT * FROM yasai_item";
$sth = $pdo -> query($sql);
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC); //$aryItemに配列を代入
//prepareの場合
$sql = "SELECT * FROM yasai_item";
$sth = $pdo -> prepare($sql);
$sth -> execute();
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC); //$aryItemに配列を代入

取得できる配列の形式

fetch、fetchAll、そしてそれぞれの()に含める引数によって、配列の形式を変更することが出来ます。

本当はもっと種類がありますが、よく使うものとして以下の4つのパターンをご確認ください。

PDO::FETCH_ASSOC PDO::FETCH_COLUMN
fetchAll 全行全列 全行1列
fetch 1行全列 1行1列
(配列ではなく変数)

参考 【PHP】PDOのfetchで取得できる配列パターン一覧

fetchAll(PDO::FETCH_ASSOC) すべてのデータを取得

fetchAll(PDO::FETCH_ASSOC)は、全行全列指定ですべてのデータを取得します。

id name price
1 にんじん 50
2 トマト 100
3 きゅうり 80

1行毎に連番で、カラム名が添え字となった連想配列が各行にセットされています。

サンプルコード
$sql = "SELECT * FROM yasai_item";
$sth = $pdo -> query($sql);
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC); //$aryItemに配列を代入

print_r($aryItem);
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => にんじん
            [price] => 50
        )

    [1] => Array
        (
            [id] => 2
            [name] => トマト
            [price] => 100
        )

    [2] => Array
        (
            [id] => 3
            [name] => きゅうり
            [price] => 80
        )

)

fetchAll(PDO::FETCH_COLUMN) 指定カラムのデータのみ取得

fetchAll(PDO::FETCH_ASSOC)は、指定したカラムのデータのみを一次元配列で取得します。

id name price
1 にんじん 50
2 トマト 100
3 きゅうり 80

SELECTで指定したいカラム名を設定してください。
「SELECT *~」など複数ある場合は一番左列が対象となります。

サンプルコード
$sql = "SELECT name FROM yasai_item";
$sth = $pdo -> query($sql);
$aryItem = $sth -> fetchAll(PDO::FETCH_COLUMN); //$aryItemに配列を代入

print_r($aryItem);
Array
(
    [0] => にんじん
    [1] => トマト
    [2] => きゅうり
)

fetch(PDO::FETCH_ASSOC) 指定した行のデータのみ取得

fetch(PDO::FETCH_ASSOC)は、指定した行(一意のid等)のカラム毎のデータの取得が可能です。

id name price
1 にんじん 50
2 トマト 100
3 きゅうり 80

通常はWHEREなどで条件を付けてから、1行で取得する前提でクエリを組みます。
データが複数あった場合は、一番最初の行を取得します。

サンプルコード
$sql = "SELECT * FROM yasai_item WHERE id = 2";
$sth = $pdo -> query($sql);
$aryItem = $sth -> fetch(PDO::FETCH_ASSOC); //$aryItemに配列を代入

print_r($aryItem);
Array
(
    [id] => 2
    [name] => トマト
    [price] => 100
)

fetch(PDO::FETCH_COLUMN) 指定行、指定カラムの値を変数で取得

fetch(PDO::FETCH_COLUMN)は、行もカラムも指定されている場合に使用します。

id name price
1 にんじん 50
2 トマト 100
3 きゅうり 80

この場合、データは1つなので、返り値は配列ではなく単一の変数となります。

サンプルコード
$sql = "SELECT name FROM yasai_item WHERE id = 2";
$sth = $pdo -> query($sql);
$item_name = $sth -> fetch(PDO::FETCH_COLUMN); //$item_nameに変数を代入

echo $item_name;
トマト

結果の配列をforeachでループさせて表示する

無事PDOから配列を取得できた場合は、foreachなどのループでデータを表示させてみましょう。

参考 PHPのforeachを徹底解説【サンプルコード有】

サンプルコード
$sql = "SELECT * FROM yasai_item";
$sth = $pdo -> query($sql);
$aryItem = $sth -> fetchAll(PDO::FETCH_ASSOC);

foreach($aryItem as $value){
    echo $value['name'].':'.$value['price']."円<br>";
}
にんじん:50円
トマト:100円
きゅうり:80円

SELECTの件数を取得する方法

PDOのSELECT文から、結果の件数(行数)を取得する方法は主に2つあります。

rowCountを使用する

PDOには、結果の対象件数を数値で取得できるrowCount()というメソッドがあります。

参考 【PHP】PDOで件数を取得するrowCountの使い方

サンプルコード
$sql = "SELECT * FROM yasai_item";
$sth = $pdo -> query($sql);
$count = $sth -> rowCount();

echo $count.'件のデータを取得しました。';
3件のデータを取得しました。

SELECT COUNT(*)~で取得する

PHP側(PDO側)ではなく、SQLのSELECT文で使用できるCOUNT()で件数を取得する方法もあります。

件数のみを取得する場合は変数で良いため、fetch(PDO::FETCH_COLUMN)を使用します。

サンプルコード
$sql = "SELECT COUNT(*) FROM yasai_item";
$sth = $pdo -> query($sql);
$count = $sth -> fetch(PDO::FETCH_COLUMN);

echo $count.'件のデータを取得しました。';
3件のデータを取得しました。

PDOを使用する場合、SELECT文は切っても切り離せない存在なので、しっかり仕様を身に着けておきましょう。

以上、PDOでSELECTの使い方、でした。

PHP