PHPとデータベース - SELECT

提供:MochiuWiki : SUSE, EC, PCB
2024年12月28日 (土) 03:00時点におけるWiki (トーク | 投稿記録)による版 (→‎単一のレコードの抽出)
ナビゲーションに移動 検索に移動

概要

データベース操作において、最初に行うものは接続の確立である。

この時、データベースのホスト名、データベース名、ユーザ名、パスワード等の接続情報を指定する。
また、文字セットはUTF-8、エラーモードを適切に設定する。

プリペアドステートメントは、SQLインジェクション対策として不可欠な機能である。
クエリの中で変数を直接使用せず、プレースホルダーを使用することで、SQLインジェクション攻撃からアプリケーションを守ることができる。

データの取得方法には主に2つのアプローチがある。

  • fetchメソッド
    1レコードずつ取得する。
    大規模なデータセットを扱う場合は、メモリ効率を考慮してfetchメソッドを使用したループ処理が推奨される。
  • fetchAllメソッド
    結果セット全体を1度に取得する。


トランザクション処理は、複数のクエリを1つの論理的な単位として実行する場合に使用する。
トランザクションを使用することにより、データの整合性を保ちながら、複数の操作を安全に実行することができる。

また、データベース接続のクリーンアップも重要である。
使用が終わったステートメントやデータベース接続は、適切にクローズする必要がある。
これにより、システムリソースを効率的に管理することができる。


単一のレコードの抽出

PDO::fetchメソッドは、1レコードのみ取得する。

 try {
    $pdo = new PDO(
       'mysql:host=<ホスト名またはIPアドレス>;dbname=<データベース名>;charset=utf8mb4',
       '<DBユーザ名>',
       '<DBユーザのパスワード>',
       [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
 
    $stmt = $pdo->prepare('SELECT * FROM users');
    $stmt->execute();
 
    $record = $pdo->fetch(PDO::FETCH_ASSOC)
 }
 catch (PDOException $e) {
    die('接続エラー: ' . $e->getMessage());
 }


繰り返し文を使用することにより、該当する複数のレコードを取得することができる。

※注意
大量のレコードを処理する場合は、メモリ使用量を考慮してfetchメソッドを使用したループ処理が推奨される。

 try {
    $pdo = new PDO(
       'mysql:host=<ホスト名またはIPアドレス>;dbname=<データベース名>;charset=utf8mb4',
       '<DBユーザ名>',
       '<DBユーザのパスワード>',
       [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
 
    $stmt = $pdo->prepare('SELECT * FROM users');
    $stmt->execute();
 
    while ($record = $pdo->fetch(PDO::FETCH_ASSOC)) {
       echo htmlspecialchars($record['name'], ENT_QUOTES, 'UTF-8');
       echo htmlspecialchars($record['address'], ENT_QUOTES, 'UTF-8');
    }
 }
 catch (PDOException $e) {
    die('接続エラー: ' . $e->getMessage());
 }
 
 $stmt = null;
 $pdo  = null;



複数のレコードの取得

PDO::fetchAllメソッドは、該当するレコードを全て取得して、連想配列に変換する。
複数のレコードに対して処理を行う場合は、その連想配列をforeach文で1レコードずつ取得する。

 $records = $pdo->fetchAll(PDO::FETCH_ASSOC);
 
 foreach ($records as $record) {
    echo htmlspecialchars($record['name']);
    echo htmlspecialchars($record['address']);
 }


以下の例では、usersテーブルから指定値以上のageカラムのレコードを全件抽出している。

 $stmt = $pdo->prepare('SELECT * FROM users WHERE age > :age');
 $stmt->execute([':age' => 20]);
 $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
 
 foreach ($records as $record) {
    echo htmlspecialchars($record['name'], ENT_QUOTES, 'UTF-8');
    echo htmlspecialchars($record['address'], ENT_QUOTES, 'UTF-8');
 }