2016-07-16 17 views
1

を働いていない、私はフライトの検索結果を返すためにPHPの関数を作っていた、これは私のコードです:PDO bindParamは、日付のために、私はPDOでの初心者です

$db = DB::getConnection(); 
$stmt = $db->prepare("SELECT * FROM `flights` WHERE `date` BETWEEN :befDate AND :aftDate 
        AND `from` = :from 
        AND `to` = :to 
        AND `weight` >= :weight"); 
$stmt->bindParam(':befDate', $befDate, PDO::PARAM_STR); //$befDate = '2016-07-21'; 
$stmt->bindParam(':aftDate', $aftDate, PDO::PARAM_STR); //$aftDate = '2016-07-28'; 
$stmt->bindParam(':from', $from, PDO::PARAM_INT); 
$stmt->bindParam(':to', $to, PDO::PARAM_INT); 
$stmt->bindParam(':weight', $weight, PDO::PARAM_INT); 
$ok = $stmt->execute(); 
if ($ok) { 
    if ($stmt->fetchColumn()>=1) { 
     $result = $stmt->fetchAll(); 
    } 
    else{ 
     $result = 'nope'; 
    } 
    return $result; 
} 
else{ 
    return false; 
} 

問題は、それが常に0を返すされていますの検索結果。私は私のSQLを実行しようとしたPDOによって生成されたSQLがあるので、phpMyAdminの中に手動で機能を介して生成し、その問題があるが見つかりました:

"SELECT * FROM `FLIGHTS` WHERE `DATE` BETWEEN '2016-07-17' AND '2016-07-25' AND `FROM` = 1237 AND `TO` = 2380 AND `WEIGHT` >= 4" 

"SELECT * FROM `FLIGHTS` WHERE `DATE` BETWEEN 2016-07-17 AND 2016-07-25 AND `FROM` = 1237 AND `TO` = 2380 AND `WEIGHT` >= 4" 

私は結果がでなければなりません取得しています、そこから正しいSQLながら、

つまり、一重引用符で囲まれた日付の値です。私はPDOでの私のSQLに引用符を追加した場合、今のように:エラー:

$stmt = $db->prepare("SELECT * FROM `flights` WHERE `date` BETWEEN ':befDate' AND ':aftDate' 
         AND `from` = :from 
         AND `to` = :to 
         AND `weight` >= :weight"); 

は、私が「束縛変数の数がトークンの数と一致していない無効なパラメータ番号」を取得します。 事前にお手伝いいただきありがとうございます!

UPDATE:

私の "フライト" のテーブル構造は次のとおりです。

CREATE TABLE `flights` (
    `fid` int(30) NOT NULL, 
    `user_id` int(30) NOT NULL, 
    `date` date NOT NULL, 
    `from` int(30) NOT NULL, 
    `to` int(30) NOT NULL, 
    `weight` int(30) NOT NULL, 
    `size` varchar(30) NOT NULL, 
    `details` varchar(200) NOT NULL, 
    `price` int(50) NOT NULL, 
    `airline` varchar(100) NOT NULL, 
    `pnr` varchar(100) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

私は、クエリからすべての引用符を削除しようとしただけでなく、単一の切れ目のないラインにそれを置く:

$stmt = $db->prepare("SELECT * FROM flights WHERE date BETWEEN :befDate AND :aftDate AND from = :from AND to = :to AND weight >= :weight"); 

まだ動作していません...

UPDATE 2 paramsをPDO(一重引用符のない文)にバインドした後のSQL文の様子を調べるには、関数の最初にSQLと同じセッション変数を作成し、結果を表示するようにエコーしました。

$_SESSION['err'] = "SELECT * FROM flights WHERE date BETWEEN $befDate AND $aftDate 
         AND from = $from 
         AND to = $to 
         AND weight >= $weight"; 
+0

それがそのまま動作するはずですが、そこに何かがあると思います。「正しい」SQLが実際に動作するのは確かですか?たぶんdatetime列がありますか? – Mihai

+0

あなたのコードに '// $ befDate = '2016-07-21''と' // $ aftDate =' 2016-07-28 'と言ったコメントがあることに気付くことはできません。出力は「BETWEEN」2016-07-17 'AND' 2016-07-25'''となると予想しています。これはおそらく結果が得られない理由です。 –

+0

質問を編集して私の質問に答えました。そうでなければ出力はphpMyAdminで働いています – Echoes

答えて

3

これはあなたの主な問題です:

if ($stmt->fetchColumn()>=1) { 
    $result = $stmt->fetchAll(); 
} 
else{ 
    $result = 'nope'; 
} 

fetchColumn()の呼び出しがその最初の行を過ぎて、結果セットを進めます。次に、fetchAll()を呼び出すと、の残りの行がの行だけがフェッチされます。それは戻って、最初の行をフェッチすることはできません、それは失われています。したがって、クエリの結果に行が1つしかない場合、その行は決して表示されません。

代わりに、私はこのコードをお勧めします:

$result = $stmt->fetchAll(); 
if (empty($result)) { 
    $result = "nope"; 
} 

その他のヒント:

は、引用符の内側にパラメータプレースホルダを置いてはいけません。もしあなたがそうするなら、パラメータプレースホルダではなく、 ":befDate"のようなリテラル文字列です。これらは有効な日付リテラルではありません。

BETWEEN :befDate AND :aftDateのような式のパラメータは、クエリとしてBETWEEN 2016-07-17 AND 2016-07-25を生成しません。パラメータは決してそのような式になることはなく、パラメータごとに常にスカラー値(たとえば、引用符付きの日付リテラル)になります。

あなたのコードを試しました。

mysql> SET GLOBAL general_log = ON; 

今、私はMySQLはPDOが提出したクエリであると考え、まさに見ることができます:まず、私は、MySQLの一般クエリログを有効に。私は、PHPスクリプトを実行した、と(私の仮想マシン上で/var/lib/mysql/localhost.log)私の一般クエリログをお読みください。

160716 19:26:16  8 Connect [email protected] on test 
      8 Query SELECT * FROM `flights` WHERE `date` BETWEEN NULL AND NULL 
        AND `from` = NULL 
        AND `to` = NULL 
        AND `weight` >= NULL 
      8 Quit 

ああ、私はパラメータにバインドされた変数の値を設定するのを忘れ。これらの変数に値がない場合、NULLとの比較が真でないため、結果が空である理由を説明します。だから私は最初に変数にサンプル値を設定するためにPHPを編集しました。

$befDate = '2016-07-21'; 
$aftDate = '2016-07-28'; 
$from = 1; 
$to = 2; 
$weight = 10; 

私は再び、クエリを実行し、ログに私は、以下を参照してください。

160716 19:33:17 13 Query SELECT * FROM `flights` WHERE `date` BETWEEN '2016-07-21' AND '2016-07-28' 
        AND `from` = 1 
        AND `to` = 2 
        AND `weight` >= 10 

これは、PDOは(それが文字列や日付の場合)パラメータ化された値の前後に引用符を入れないことを証明しています。

+0

うわーと私は最後の6時間以来苦労していた!それは問題を解決しました。皮肉なことに私のテーブルには結果の行が1つしかありませんでした。助けてくれてありがとう! :D – Echoes

関連する問題