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

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

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

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

解決済

2回答

2254閲覧

sql文のセキュリティ 配列での受け渡し

space_sss

総合スコア81

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

0クリップ

投稿2016/12/25 15:12

編集2016/12/25 16:00

sql文の配列のへバインドがうまくいきません。

php

1$cont=array(1,2,3,4,);//ここは常に変わる数値 2$count_box=5;//ここは常に変わる数値 3$inClause = substr(str_repeat(',?', count($cont)), 1); 4$sql='SELECT * FROM `table` WHERE `category` IN ('.$inClause.') ORDER BY `id` DESC limit 10 offset ?'; 5$stmt=$dbh->prepare($sql); 6$cont_box=array_merge($count_box,array($cont)); 7$stmt->execute($cont_box);//ここでエラー表示 8

こちらで表示すると
Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''5'' at line 1' in アドレス:39 Stack trace: #0 アドレス(39): PDOStatement->execute(Array) #1 {main} thrown in アドレス on line 39
39行目とは
$stmt->execute($cont_box);
こちらのと文となります。
環境は
php 5.6
phpMyAdmin 5.6.23
です。
ちなみにこちらですと問題なくエラーが出ませんので配列の受け渡しによりエラーが起きてるのかな?とは推測しております。

php

1$cont=array(1,2,3,4,);//ここは常に変わる数値 2$inClause = substr(str_repeat(',?', count($cont)), 1); 3$sql='SELECT * FROM `table` WHERE `category` IN ('.$inClause.') ORDER BY `id` DESC limit 10 offset 5'; 4$stmt=$dbh->prepare($sql); 5$stmt->execute($cont); 6

ご回答お待ちしております。

さらにここで本来のリミットをかけない状態のヒットした数を数えたいので無理やりこれの前に

php

1$cont=array(1,2,3,4,);//ここは常に変わる数値 2$count_box=5;//ここは常に変わる数値 3$inClause = substr(str_repeat(',?', count($cont)), 1); 4$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); 5$sql='SELECT * FROM `table` WHERE `category` IN ('.$inClause.')'; 6$stmt=$dbh->prepare($sql); 7$stmt->execute($cont_box); 8$max=$stmt->rowCount();

を入れていますがこちらはひとつの文に出来ないでしょうか?
宜しくお願いいたします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2016/12/25 15:18

「sql文の配列のへバインドがうまくいきません。」「うまくいかない」というだけでは、何がどうなっているのか伝わりません。環境の違いなどで、実行結果が変わる場合もありますので、「どうなると思って」「どうなった」のかがわかるように記述してください。
space_sss

2016/12/25 15:23

エラー内容を記述しました。宜しくお願いいたします。
guest

回答2

0

ベストアンサー

php

1<?php 2 3ini_set('display_errors', 1); 4error_reporting(E_ALL); 5 6try { 7 $dsn = 'mysql:host=localhost;dbname=sample;charset=utf8'; 8 $username = 'root'; 9 $password = 'password'; 10 $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; 11 12 $dbh = new PDO($dsn, $username, $password, $options); 13 14 $cont = array(1, 2, 3, 4); //ここは常に変わる数値 15 $offset = 5; 16 17 $sql = 'SELECT * FROM `table` '; 18 $sql .= 'WHERE 1 '; 19 20 $arrParams = []; 21 foreach ($cont as $val) { 22 $placeholder[] = '?'; 23 $arrParams[] = $val; 24 } 25 $sql .= 'AND `category` IN (' . implode(',', $placeholder) . ') '; 26 $sql .= 'ORDER BY `id` DESC '; 27 $sql .= sprintf('limit 10 offset %d', $offset); 28 29 $stmt = $dbh->prepare($sql); 30 $stmt->execute($arrParams); 31} catch (Exception $e) { 32 echo $e->getMessage(); 33}

$stmt->execute($arrParams); これで値をバインドすると、全てのパラメータが文字列としてバインドされます。
すると、 limit 10 offset '5' というSQLが実行されることとなり、SQLエラーになるのです。

投稿2016/12/25 17:46

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

space_sss

2016/12/25 19:07

$stmt->execute($arrParams); でバイントすると文字列扱いになってしまうのですね。 その場合はどういった手段を使えばよろしいのでしょうか?
退会済みユーザー

退会済みユーザー

2016/12/25 19:10 編集

> その場合はどういった手段を使えばよろしいのでしょうか? 提示したコード見てないのでしょうか?
space_sss

2016/12/25 19:17

上記のコードをしっかり確認したところ問題なく解決いたしました。 ご教授ありがとうございました。
space_sss

2016/12/25 19:18

コードがなぜか表示されていませんでしたがリロードしたら表示されました! お手数をおかけいたしました。
guest

0

あぁ、$inClauseってそういう用途でしたか・・・

投稿2016/12/25 16:03

編集2016/12/25 23:28
zico_teratail

総合スコア907

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

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

space_sss

2016/12/25 19:06

なぞのコードで申し訳ありません。 こちらですと疑問符プレースホルダと名前付きプレースホルダが入ってしまうことによりエラーが出るのではないのでしょうか?
space_sss

2016/12/26 04:19

こちらこそ見にくいコードで大変申し訳ありません… ご解答ありがとうございました!
zico_teratail

2016/12/26 04:38

こちらこそ的外れな回答してすみません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問