質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

3620閲覧

mysqli関数でプリペアドステートメントを利用してselect文を実行した際の結果の取得について

orange0190

総合スコア1698

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2015/05/18 02:37

かなり長いと思いますが、ご了承ください。
以下のコードは自作のライブラリの一部で、PHPでmysqli関数利用の場合、mysql関数利用の場合(mysql関数が非推奨なのは承知しているが念のため)、PDO利用の場合、それぞれでmysqlのデータベースでselect文を実行するものになります。
この関数の返り値は「数字添字配列形式の実行結果の数字添字配列」となるのですが、それを「オブジェクト形式の実行結果の数字添字配列」で返したいです。
mysql利用およびPDO利用の場合ではできるのですが、mysqli利用の場合でオブジェクト形式にできません。

どうかご教授をお願いします。mysqliは手続き型でお願いします。

lang

1 //------------------------------------------------------------------------------ 2 // SELECT文を実行する 3 // 4 // パラメータ 5 // $_tableName:テーブル名 6 // $_items:取得する項目 配列で入力 7 // $_andWhere:ANDで結ぶ条件 array(array(対象, 条件, 評価値),...)の形で入力 8 // $_orWhere:ORで結ぶ条件 array(array(対象, 条件, 評価値),...)の形で入力 9 // $_order:ORDER BY の文 array(array(対象, タイプ),...)の形で入力 10 // $_limit:LIMITの数値 11 // $_offset:OFFSETの数値 12 // 13 // 返り値 14 // mixed SQLの実行に成功したなら数字添字配列形式の実行結果の数字添字配列 失敗したならfalse 15 //------------------------------------------------------------------------------ 16 public function select($_tableName = '', $_items = null, $_andWhere = null, $_orWhere = null, $_order = null, $_limit = '', $_offset = '') 17 { 18 //タイプ取得 19 $_type = $this->dbType; 20 //テーブル名をチェック 21 if(!$_tableName){ 22 $this->dbErr = __LINE__ . ' : Bad arguents. in $_tableName'; 23 $this->dbErrNo = $this->dbType . '_' . SEL_TBL_ERR; 24 throw new DBException($this->dbErr, $this->dbErrNo); 25 } 26 //SELECT文を作成開始 27 $_sql = 'SELECT '; 28 //取得アイテムを羅列 29 if(!$_items or $_items === '*'){ 30 //取得アイテムに指定がない場合には、全アイテムを取得 31 $_sql .= '*'; 32 } else { 33 if(!is_array($_items)){ 34 //取得アイテムが配列じゃない場合には例外を発生させる 35 $this->dbErr = __LINE__ . ' : Bad arguents. $_item will need to be in the array in "select($_tableName, $_items, $_andWhere, $_orWhere, $_order, $_limit, $_offset)".'; 36 $this->dbErrNo = $this->dbType . '_' . SEL_ITEM_ERR; 37 throw new DBException($this->dbErr, $this->dbErrNo); 38 } 39 for($_i = 0; $_i < count($_items); $_i++){ 40 $_items[$_i] = $this->backQuote($_items[$_i]); 41 } 42 //取得アイテムを結合してSQL文に追加 43 $_sql .= join(', ', $_items); 44 } 45 //SQL文にテーブル名を追加 46 $_sql .= ' FROM ' . $this->backQuote($_tableName); 47 48 //条件の部分を作成 49 $_condition = ''; 50 $_conditionAnd = ''; 51 $_conditionOr = ''; 52 53 $_replaceVal = array(); 54 55 //ANDで結合する条件 56 if($_andWhere){ 57 if(!is_array($_andWhere)){ 58 //配列じゃない場合はパラメータエラーを返す 59 $this->dbErr = __LINE__ . ' : Bad arguents. $_andWhere will need to be in the associative array in "select($_tableName, $_items, $_andWhere, $_orWhere, $_order, $_limit, $_offset)".'; 60 $this->dbErrNo = $this->dbType . '_' . SEL_WHERE_ERR; 61 throw new DBException($this->dbErr, $this->dbErrNo); 62 } 63 foreach($_andWhere as $_val){ 64 if($_conditionAnd !== ''){ 65 $_conditionAnd .= ' AND '; 66 } 67 //条件文を作成 68 $_sqlWhere = $this->sqlWherePrepare($_replaceVal, $_val[0], $_val[1], $_val[2]); 69 if(!$_sqlWhere){ 70 //作成した条件文が不正 71 $this->dbErr = __LINE__ . ' : Bad arguents. It is not possible to make a conditional statement.'; 72 $this->dbErrNo = $this->dbType . '_' . SEL_WHERE_ERR; 73 throw new DBException($this->dbErr, $this->dbErrNo); 74 } 75 $_conditionAnd .= $_sqlWhere; 76 } 77 } 78 if($_conditionAnd !== ''){ 79 if($_condition !== ''){ 80 $_condition .= ' AND (' . $_conditionAnd . ')'; 81 } else { 82 $_condition = ' WHERE (' . $_conditionAnd . ')'; 83 } 84 } 85 86 //ORで結合する条件 87 if($_orWhere){ 88 if(!is_array($_orWhere)){ 89 //配列じゃない場合はパラメータエラーを返す 90 $this->dbErr = __LINE__ . ' : Bad arguents. $_orWhere will need to be in the associative array in "select($_tableName, $_items, $_andWhere, $_orWhere, $_order, $_limit, $_offset)".'; 91 $this->dbErrNo = $this->dbType . '_' . SEL_WHERE_ERR; 92 throw new DBException($this->dbErr, $this->dbErrNo); 93 } 94 foreach($_orWhere as $_val){ 95 if($_conditionOr !== ''){ 96 $_conditionOr .= ' OR '; 97 } 98 //条件文を作成 99 $_sqlWhere = $this->sqlWherePrepare($_replaceVal, $_val[0], $_val[1], $_val[2]); 100 if(!$_sqlWhere){ 101 //作成した条件文が不正 102 $this->dbErr = __LINE__ . ' : Bad arguents. It is not possible to make a conditional statement.'; 103 $this->dbErrNo = $this->dbType . '_' . SEL_WHERE_ERR; 104 throw new DBException($this->dbErr, $this->dbErrNo); 105 } 106 $_conditionOr .= $_sqlWhere; 107 } 108 } 109 if($_conditionOr !== ''){ 110 if($_condition !== ''){ 111 $_condition .= ' AND (' . $_conditionOr . ')'; 112 } else { 113 $_condition = ' WHERE (' . $_conditionOr . ')'; 114 } 115 } 116 117 //条件文をSQL文に追加 118 if($_condition !== ''){ 119 $_sql .= $_condition; 120 } 121 122 //ORDER BYの部分を作成 123 $_orderBy = ''; 124 if($_order){ 125 if(!is_array($_order)){ 126 //配列じゃない場合はパラメータエラーを返す 127 $this->dbErr = __LINE__ . ' : Bad arguents. $_order will need to be in the associative array in "select($_tableName, $_items, $_andWhere, $_orWhere, $_order, $_limit, $_offset)".'; 128 $this->dbErrNo = $this->dbType . '_' . SEL_ORDER_ERR; 129 throw new DBException($this->dbErr, $this->dbErrNo); 130 } 131 foreach($_order as $_val){ 132 if(!is_array($_val)){ 133 //配列じゃない場合はパラメータエラーを返す 134 $this->dbErr = __LINE__ . ' : Bad arguents. $_order will need to be in the associative array in "select($_tableName, $_items, $_andWhere, $_orWhere, $_order, $_limit, $_offset)".'; 135 $this->dbErrNo = $this->dbType . '_' . SEL_ORDER_ERR; 136 throw new DBException($this->dbErr, $this->dbErrNo); 137 } 138 if(count($_val) != 2){ 139 //要素数が2じゃない場合はパラメータエラーを返す 140 $this->dbErr = __LINE__ . ' : Bad arguents. The number of elements in the elements of $_order must be 2.'; 141 $this->dbErrNo = $this->dbType . '_' . SEL_ORDER_ERR; 142 throw new DBException($this->dbErr, $this->dbErrNo); 143 } 144 145 if($_orderBy === ''){ 146 $_orderBy = $this->backQuote($_val[0]) . ' ' .$_val[1]; 147 } else { 148 $_orderBy .= (', ' . $this->backQuote($_val[0]) . ' ' .$_val[1]); 149 } 150 } 151 } 152 153 //SQL文にORDER BY を追加 154 if($_orderBy !== ''){ 155 $_sql .= ' ORDER BY ' . $_orderBy; 156 } 157 158 //LIMIT OFFSETの部分を作成 159 $_limitPart = ''; 160 if($_limit !== ''){ 161 if($_offset !== ''){ 162 $_limitPart = ' LIMIT ' . $_offset . ', ' . $_limit; 163 } else { 164 $_limitPart = ' LIMIT ' . $_limit; 165 } 166 } 167 168 //SQL文にLIMIT OFFSETを追加 169 if($_limitPart !== ''){ 170 $_sql .= $_limitPart; 171 } 172 173 //SQLを実行する **********************ここ以降を教えてほしいです。 174 if($_type == 1){ 175 //mysqliの場合 176 //プリペアドステートメントの準備 177 $_stmt = mysqli_stmt_init($this->dbCon); 178 //プリペアドステートメントの作成 179 if(!$_result = mysqli_stmt_prepare($_stmt, $_sql)){ 180 $this->dbErr = __LINE__ . ' : SQL execution failure. Because "' . mysqli_stmt_error($_stmt) . '"'; 181 $this->dbErrNo = $this->dbType . '_' . SEL_EXEC_ERR; 182 throw new DBException($this->dbErr, $this->dbErrNo); 183 } 184 //置き換える値の種類を設定 185 $_paramStr = ''; 186 for($_i = 0; $_i < count($_replaceVal); $_i++){ 187 $_varType = gettype($_replaceVal[$_i]); 188 switch($_varType){ 189 case 'string': 190 $_paramStr .= 's'; 191 break; 192 case 'integer': 193 $_paramStr .= 'i'; 194 break; 195 case 'double': 196 $_paramStr .= 'd'; 197 break; 198 default: 199 break; 200 } 201 } 202 //任意の数の引数を引き渡したいのでcall_user_func_arrayを利用 203 //call_user_func_arrayへ渡す引数の設定 204 $_stmtParams = array($_stmt, $_paramStr,); 205 for($_i = 0; $_i < count($_replaceVal); $_i++){ 206 $_stmtParams[] = &$_replaceVal[$_i]; 207 } 208 if(count($_replaceVal) > 0){ 209 if(!$_result = call_user_func_array('mysqli_stmt_bind_param', $_stmtParams)){ 210 $this->dbErr = __LINE__ . ' : ' . mysqli_stmt_error($_stmt); 211 $this->dbErrNo = $this->dbType . '_' . SEL_EXEC_ERR; 212 throw new DBException($this->dbErr, $this->dbErrNo); 213 } 214 } 215 //ここでSQLを実行 216 if(!$_result = mysqli_stmt_execute($_stmt)){ 217 $this->dbErr = __LINE__ . ' : SQL execution failure. Because "' . mysqli_stmt_error($_stmt) . '"'; 218 $this->dbErrNo = $this->dbType . '_' . SEL_EXEC_ERR; 219 throw new DBException($this->dbErr, $this->dbErrNo); 220 } 221 $_fieldCount = mysqli_stmt_field_count($_stmt); 222 $_binds = array($_stmt); 223 $_bindsParam = array(); 224 for($_i = 0; $_i < $_fieldCount; $_i++){ 225 $_binds[] = &$_bindsParam[$_i]; 226 } 227 if(!$_result = call_user_func_array('mysqli_stmt_bind_result', $_binds)){ 228 $this->dbErr = __LINE__ . ' : SQL execution failure. Because "' . mysqli_stmt_error($_stmt) . '"'; 229 $this->dbErrNo = $this->dbType . '_' . SEL_EXEC_ERR; 230 throw new DBException($this->dbErr, $this->dbErrNo); 231 } 232 $_resultRows = array(); 233 while(mysqli_stmt_fetch($_stmt)){ 234 $_row = array(); 235 for($_i = 0; $_i < $_fieldCount; $_i++){ 236 $_row[] = $_binds[$_i + 1]; 237 } 238 $_resultRows[] = $_row; 239 } 240 mysqli_stmt_close($_stmt); 241 return $_resultRows; 242 } else if($_type == 2) { 243 //mysqlの場合 244 } else if($_type == 3) { 245 //PDOの場合 246 } else { 247 $this->dbErr = __LINE__ . ' : You can not run the SQL.'; 248 $this->dbErrNo = $this->dbType . '_' . SEL_EXEC_ERR; 249 throw new DBException($this->dbErr, $this->dbErrNo); 250 } 251 } 252

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

mysqli_stmt_execute の後で mysqli_stmt_get_result して mysqli_fetch_object すると良いと思います。

lang

1$db = mysqli_connect("localhost", "test", "pass", "test"); 2$sql = "select id from t"; 3$stmt = mysqli_prepare($db, $sql); 4mysqli_stmt_execute($stmt); 5$result = mysqli_stmt_get_result($stmt); 6$rows = array(); 7while ($row = mysqli_fetch_object($result)) { 8 $rows[] = $row; 9} 10var_dump($rows);

投稿2015/05/18 03:37

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

orange0190

2015/05/18 04:49

ありがとうございます。 おかげでオブジェクト形式での取得ができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問