1

プリペアドステートメントを利用するために、MySQLコードをPDOに変換しています。この質問で説明されているように、私はもともと致命的なエラーが発生していました。私はその問題を解決しましたが、パラメーターを追加しようとするとさらに多くの問題が発生しました。

私が動作させようとしているコードは次のとおりです。

include ("foo/bar.php");

try {
     $DBH = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
    }  
catch(PDOException $e) {  
    echo $e->getMessage();  
    }

    $mydate=date("Y-m-d",strtotime("-3 months"));

    $foo_query=$DBH->prepare("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = :postdate AND postdate > '$mydate' ORDER BY postdate DESC");
    $foo_query->execute( array('postdate' => $_REQUEST['postdate']) );

    $DBH=null;

英語では、これは「現在の日付を取得して3か月前に戻し、$ mydateと呼んでから、テーブルからこれらのフィールドをすべて選択します(本文の最初の20語を取得し、「preview_text」と呼びます)。ここで、postdateはパラメーターpostdateと等しく、postdateは$mydate "より大きいです。

次に、結果を次のように表示します(これは現在要約されていることに注意してください)。

$foo_query->setFetchMode(PDO::FETCH_ASSOC);
    while($r=$foo_query->fetch()) {
    echo $r["id"];
    echo $r["title"];
    echo date("d-M-Y",strtotime($r["postdate"]));
    echo nl2br ($r["preview_text"]); }

ここで、SELECTクエリは次のように記述されます。

("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate > '$mydate' ORDER BY postdate DESC")

...必要なものが正確に表示されますが、もちろんこれが準備されている間はパラメーターが含まれていないため、目標の50%しか達成できません。

私は、私が最初に概説した声明を準備する方法が、私がすでに与えられたチュートリアルとアドバイスに従ってうまくいくだろうという印象を受けました。

エラーを印刷しようとしましたが、エラーは発生しません。次のように手動でクエリを送信しましたが、返されません。あらゆる種類の順列で日付文字列を試したことに注意してください。

("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = 20121001 AND postdate > 20120701 ORDER BY postdate DESC")

編集:上記は間違っていると指摘されましたが、このセクションは以下のコメントで説明されているので、参照用にここに保管しておきます。

編集:手動でクエリを送信すると、入力時に正しく表示されるようになりました。

("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = '2012-09-30 08:38:23' ORDER BY postdate DESC")

次のいずれかを入力すると、クエリはまったく表示されません。

("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = :postdate ORDER BY postdate DESC")
("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = :postdate AND postdate > '$mydate' ORDER BY postdate DESC")
("SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body FROM BarTable WHERE postdate = '2012-09-30 08:38:23' AND postdate > '2012-07-01 00:01' ORDER BY postdate DESC")

何らかの方法でパラメーターをバインドする必要があると考えていますが、読んだチュートリアルでは、常にパラメーターをバインドする必要があると具体的には述べていません。どのように進めるかがわかりません。

編集:私は次のようにステートメントをバインドしようとしましたが、成功しませんでした。クエリはバインドを無視しているように見えるため、クエリの状態はバインドなしで上記のすべての順列として機能します。

$foo_query->bindParam (
   ":postdate", strtotime ( $_REQUEST['postdate']), PDO::PARAM_INT);
$foo_query->execute();

パラメータを追加しないと、何が間違っているのでしょうか。SELECTクエリ以外の場所で:postdateパラメータを宣言する必要がありますか?

SQLインジェクションを防ぐために、ステートメントの準備だけでなく名前付きパラメーターも使用したいと思いますが、理解できない場合は、名前付きパラメーターを使用しないでください。

4

1 に答える 1

1

配列を介してパラメーターを使用する場合、デフォルトのパラメータータイプでバインドしますPDO::PARAM_STR

データ型に応じて:

  • MySQLタイムスタンプデータ型:同じです。文字列として渡します
  • 整数であるPHPUnixタイムスタンプ:intを渡します。

次のようにコードを変更することをお勧めします。

$foo_query=$DBH->prepare(
   "SELECT id, postdate, title, SUBSTRING_INDEX(body,' ',20) as preview_text, body 
    FROM BarTable WHERE postdate = :postdate 
    ORDER BY postdate DESC");
$foo_query->bindParam (
   ":postdate", strtotime ( $_REQUEST['postdate']), PDO::PARAM_INT); 
//                                                  ^^^ bind as integer
$foo_query->execute(); 
于 2012-10-02T15:40:02.917 に答える