【PHP】 プリペアドステートメントの結果を連想配列に変換

プリペアドステートメントは同じ処理を繰り返す時に非常に便利です。

しかし、困ったことに結果取得が非常に面倒です。

いちいち結果を格納する変数をbind_result()で宣言しなければいけません。

しかも、変数をひとつずつ列挙しなければいけないというなんとも使い勝手が悪い仕様です。

クエリーであればfetch_all()で一発で連想配列に変換してくれますが、

プリペアドステートメントにはそんな便利なものはありません。

 

絶対にこれは困るだろうなとネットを検索してみたら

やはり多くの人が困っていたみたいで自作の関数を作っている方がいました。

ありがたくこちらを使わせていただきました。

 

function fetch_all(& $stmt) {
    $hits = array();
    $params = array();
    $meta = $stmt->result_metadata();
    while ($field = $meta->fetch_field()) {
        $params[] = &$row[$field->name];
    }
    call_user_func_array(array($stmt, 'bind_result'), $params);
    while ($stmt->fetch()) {
      $c = array();
      foreach($row as $key => $val) {
        $c[$key] = $val;
      }
      $hits[] = $c;
    }
    return $hits;
 }

 

この関数では大きく分けて3つのことをしています。

  1. 結果のメタデータから情報取得 (4~7行目)
  2. メタデータをバインド (8行目)
  3. バインドした結果を配列に格納 (9~15行目)

 

1.結果のメタデータから情報取得

4行目では、結果のメタデータオブジェクトを取得しています。

メタデータオブジェクトからメタデータにアクセスしていきます。

5行目でメタデータのカラム名を取得しています。

$field = $meta->fetch_field()
/*メタデータカラム名の種類
*name:テーブルのカラム名
*table:テーブル名
*db:データベース名   etc...
*/

そして6行目でテーブルのカラム名を連想配列のキーとして$params配列に格納しています

これで、結果を格納する連想配列の準備が整いました。

 

2.メタデータをバインド

7行目で、bind_result()を呼び出し、結果をバインドしています。

call_user_func_array(array($result, 'bind_result'), $params)

//第1引数には呼び出す関数を
//第2引数には呼び出した関数に渡す変数を

 

 

3.バインドした結果を連想配列に格納

9行目のfetch()でバインドした結果を実際に取得していきます。

11、12行目でカラムのデータを1レコード分にまとめ、

14行目で検索結果の全レコードをひとつの配列に格納しています。

 

この関数を使うと、便利だったプリペアードステートメントがさらに便利になります。