こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

PHP PDO化作業中ORDERでソートできない

WAMP初級者です。
いままでPEAR::DBを使って書いていたサイトがあり、PDOを利用するように書き換えていますが、いろいろ試してもorderでの並び替えが効いてくれません。どなたかアドバイス頂けないでしょうか。
該当箇所のみ切り出して例示いたします。
キーワード検索した結果画面で、$keywordはPOSTで渡って来ています。

●うまくいく例(画面に期待したものが表示される)
$connection=new PDO('mysql:host=localhost;dbname=test_db','root','root');
$connection->query('SET NAMES utf8');
$query="select * from test_tbl join test2_tbl using(Code) where NameW lik
e :keyword";

$stmt=$connection->prepare($query);
$stmt->bindValue(":keyword","%$keyword%",PDO::PARAM_STR);
$stmt->execute();


●これだと画面が真っ白になる(オーダーでソートしたいのですが。。)
$orderKB="10K+10B";
$direction = "desc";
$connection=new PDO('mysql:host=localhost;dbname=test_db','root','root');
$connection->query('SET NAMES utf8');
$query="select * from test_tbl join test2_tbl using(Code) where NameW lik
e :keyword order by :orderKB :direction";

$stmt=$connection->prepare($query);
$stmt->bindValue(":keyword","%$keyword%",PDO::PARAM_STR);
$stmt->bindValue(":orderKB", $orderKB, PDO::PARAM_STR);
$stmt->bindValue(":direction", $direction, PDO::PARAM_STR);
$stmt->execute();

ちなみに、10Kと10Bというのは数字データで合計した数字の高い順に並び替えを
したいです。
初歩的な質問ですみませんが、どなたお助けいただけますと幸いです。
環境はApache/2.2.4 (Win32) PHP/5.4.22です

宜しくお願い致します。

投稿日時 - 2013-12-12 11:39:59

QNo.8383270

すぐに回答ほしいです

質問者が選んだベストアンサー

真っ白になる → エラーが発生しているということです。デバッグ環境ではphp.iniの設定で

display_errors = On
error_reporting = E_ALL | E_STRICT

としてください。

(くどいですけど一応貼っておきます)
http://qiita.com/mpyw/items/b00b72c5c95aac573b71

PHP5.4に更新されたならば、エンコーディング指定の方法を望ましい方法に変えましょう。以下にサンプルコードを掲載します。
(全角スペースでインデントしています)

● 例1

最初のうまくいった例ですが、LIKE検索に使われる特殊文字「_」「%」「\」のエスケープが行われていなかったので追記しておきました。

try {
 
 // 接続
 $pdo = new PDO(
  'mysql:host=127.0.0.1;dbname=test_db;charset=utf8',
  'root',
  'root',
  array(
   PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
   PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
   PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
  )
 );
 
 // SQL実行
 $sql = implode(' ', array(
  'SELECT *',
  'FROM `test_tbl`',
  'JOIN `test_tbl2` USING(`Code`)',
  'WHERE `NameW` LIKE ?',
 ));
 $stmt = $pdo->prepare($sql);
 $stmt->execute(array('%' . addcslashes($keyword, '%_\\') . '%'));
 
 // 表示
 foreach ($stmt as $i => $row) {
  /* 表示処理 */
 }
 
} catch (PDOException $e) {
 
 // 例外メッセージ
 echo $e->getMessage();
 
}

● 例2

「10K」「10B」という名前のカラムが存在するってことでいいんですよね?

try {
 
 // 接続
 $pdo = new PDO(
  'mysql:host=127.0.0.1;dbname=test_db;charset=utf8',
  'root',
  'root',
  array(
   PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
   PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
   PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
  )
 );
 
 // SQL実行
 $sql = implode(' ', array(
  'SELECT *',
  'FROM `test_tbl`',
  'JOIN `test_tbl2` USING(Code)',
  'WHERE `NameW` LIKE ?',
  'ORDER BY `10K` + `10B` DESC',
 ));
 $stmt = $pdo->prepare($sql);
 $stmt->execute(array('%' . addcslashes($keyword, '%_\\') . '%'));
 
 // 表示
 foreach ($stmt as $i => $row) {
  /* 表示処理 */
 }
 
} catch (PDOException $e) {
 
 // 例外メッセージ
 echo $e->getMessage();
 
}

カラム名やDESCなどの特別なキーワードをプレースホルダを使ってバインドすると、バッククオートではなくシングルクオートで括られて文字列の扱いを受けてしまうので、プレースホルダを用いることは出来ません。もしこれらを可変パラメータにする場合は、十分に入力が正しいか検証した後、prepareメソッドをコールする前の段階でsprintf関数などを活用してクエリ文を組み立てておく必要があります。

投稿日時 - 2013-12-12 13:58:36

お礼

いつもアドバイスありがとう御座います。解決いたしました。
また、サンプルコードも感謝いたします。初心者用のテキストにはなかなか出てこない上級なコードでこれだけで発見が多くありました。"PHPでデータベースに接続するときのまとめ"はいつも開きっぱなしにしてますが、初級者の私にはすべて理解ができていませんが、少しずつご指摘の内容がわかってきました。引き続きがんばって勉強します。

投稿日時 - 2013-12-14 00:44:11

このQ&Aは役に立ちましたか?

5人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問