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

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

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

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

PHP

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

Q&A

解決済

3回答

5972閲覧

MySQL ページネーション実装 LIMIT句のエラーについて

lista

総合スコア13

MySQL

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

PHP

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

0グッド

1クリップ

投稿2017/11/06 04:24

###前提・実現したいこと
PHPとMySQLを用いて、ページネーションの実装をしています。
ページネーション(ページ切り替え)の実装方法いろいろ - Qiitaを参考にしてコードを書いてみましたが、LIMIT句でエラーが発生します。

###発生している問題・エラーメッセージ

Fatal error: Uncaught PDOException: 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 ''0', 20' at line 1 in /***/index.php:16

###該当のソースコード

PHP

1$page = $_GET['page'] - 1; 2if ($page < 0) $page = 0; 3 4$sql = "SELECT * FROM table ORDER BY 'id' ASC LIMIT :offset, 20"; 5$stmt = $pdo->prepare($sql); 6$stmt->bindValue(':offset', $page * 20); 7$stmt->execute(); 8$data = $stmt->fetchAll();

###試したこと
プレースホルダを用いずに、

PHP

1$sql = "SELECT * FROM table ORDER BY 'id' ASC LIMIT ".($page*20).", 20";

とした場合には正常に動作します。
なぜプレースホルダを用いたSQL文では、構文エラーが出るのでしょうか?

###補足情報(言語/FW/ツール等のバージョンなど)
PHP7.0.18
MySQL5.7

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

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

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

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

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

guest

回答3

0

ベストアンサー

エラーをよく見てください。

near ''0', 20'

さて、0がシングルクォーテーションで囲まれているのがわかりますか?実際SQLでLIMITに渡す数値をシングルクォーテーションで囲ってみてください。同じエラーが起きます。これがなぜ起きるのか、それはbindValueで「型を指定しないとデフォルトでは文字列として埋め込まれる」からです。PDO::PARAM_INTと明示してやることで、数値として埋め込まれて正常なSQLが実行されるはずです。

PHP

1$stmt->bindValue(':offset', $page * 20, PDO::PARAM_INT);

投稿2017/11/06 04:37

masaya_ohashi

総合スコア9206

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

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

退会済みユーザー

退会済みユーザー

2017/11/06 04:40

(int)しないとダメな気がする。
maisumakun

2017/11/06 04:50

PHPの乗算演算子は数値専用なので、$pageに小数が来て結果が整数にならない場合を除けば、「$page * 20」は整数になります。
lista

2017/11/06 04:53 編集

回答ありがとうございます。データ型を指定してあげないといけないのですね、、 ご教示の通りやってみましたが、同じエラーが発生してしまいます…。 ただし、ご指摘のシングルクォーテーションは消えました。 Fatal error: Uncaught PDOException: 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 '0, 20' at line 1 in
退会済みユーザー

退会済みユーザー

2017/11/06 04:58

> maisumakun さん たしかに!はずかしい^^;
lista

2017/11/06 05:04

すみません!色々いじっているうちにtypoしてただけみたいです。データ型を指定するだけで解決しました。ありがとうございました!
masaya_ohashi

2017/11/06 05:30

ちなみに私は乗算でintになるから省略していたわけではなく、普通に見落としていただけです。指摘ありがとうございました!
guest

0

他の方が提示されているようpdoあるあるなので
bindValueにint型を指定するというのが基本ですが

limit句だけpdoから切り離し、sprintfの%dで与えてあげる手もあります。
ただしユーザーから送られてくるデータは常に汚染されている前提で
特殊なデータがくる可能性もある前提でfilter_inputで整数のチェックを入れたりしてください

投稿2017/11/06 04:43

yambejp

総合スコア114572

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

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

0

投稿2017/11/06 04:35

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問