0

私は次のSELECTようなクエリを使用しています:

SELECT knowledge.*, 
       sortflagitems.* 
FROM   knowledge, 
       sortflagitems 
WHERE  sortflagitems.flagid = :FlagID 
       AND knowledge.id = sortflagitems.kid 
       AND sortflagitems.cid = :CID 
       AND knowledge.archived = :Nothing 
       AND sortflagitems.flagdate <= :Now 
ORDER  BY sortflagitems.sortorder 

これにより、次のエラーが発生します。

 Invalid parameter number: number of bound variables does not match number of tokens

ただし、SELECTクエリを次のように変更すると:

SELECT knowledge.*, 
       sortflagitems.* 
FROM   knowledge, 
       sortflagitems 
WHERE  sortflagitems.flagid = :FlagID 
       AND knowledge.id = sortflagitems.kid 
       AND sortflagitems.cid = :CID 
       AND knowledge.archived = :Nothing 
       AND sortflagitems.flagdate = :Now 
ORDER  BY sortflagitems.sortorder 

それはエラーを生成しません

この行SortFlagItems.FlagDate=:Nowがから変更されたことに注意してくださいSortFlagItems.FlagDate<=:Now

私の唯一の理論は、何らかの理由で複数のテーブルを選択すると、演算子を使用できないということです(演算子を使用すると同じエラーが発生する<=ことに注意してください)。<他に思いつかない..


完全な PHP コードは次のとおりです。

$DBParams = array('FlagID'=>$_GET['flag'], 'CID'=>$row['CatID'], 'Nothing'=>0, 'Now'=>strtotime('now'));
$results = $Db->rquery('
                    SELECT Knowledge.*, SortFlagItems.*
            FROM Knowledge, SortFlagItems
            WHERE SortFlagItems.FlagID=:FlagID
            AND Knowledge.id = SortFlagItems.KID
            AND SortFlagItems.CID=:CID
            AND Knowledge.Archived=:Nothing
            AND SortFlagItems.FlagDate<=:Now
            ORDER BY SortFlagItems.SortOrder', $DBParams);

rquery関数は次のとおりです。

function rquery($query, $params = NULL) {
    $this->_query = filter_var($query, FILTER_SANITIZE_STRING);
    $stmt = $this->_prepareQuery();
    $stmt->execute($params);

    $results = $this->_dynamicBindResults($stmt);

    return $results;
}

そしてコンストラクタ:

public function __construct($host, $username, $password, $db) {
    $this->_mysql = new PDO("mysql:host=$host;dbname=$db", $username, $password);
    $this->_mysql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
4

1 に答える 1

1

私の解決策は、メソッドからfilter_varを削除することです。

function rquery($query, $params = NULL) {
    $this->_query = $query;
    $stmt = $this->_prepareQuery();
    $stmt->execute($params);

    $results = $this->_dynamicBindResults($stmt);

    return $results;
}

バインディングにより、SQLインジェクションが妨げられます。必要に応じて、内部のパラメータで
使用できます。filter_var()_dynamicBindResults

または、クエリを渡す前に各パラメータで使用できます。

$DBParams = array('FlagID'=>filter_var($_GET['flag'], FILTER_SANITIZE_STRING),...);

そして、ここでの結合には、明示的な結合があります。

SELECT Knowledge.*, SortFlagItems.*
FROM Knowledge
INNER JOIN SortFlagItems ON Knowledge.id = SortFlagItems.KID
WHERE SortFlagItems.FlagID=:FlagID
AND SortFlagItems.CID=:CID
AND Knowledge.Archived=:Nothing
AND SortFlagItems.FlagDate<=:Now
ORDER BY SortFlagItems.SortOrder
于 2013-02-28T20:32:58.240 に答える