0

古いMySQLIクエリをPDOに変換しようとしていますが、インジェクションから保護するためにすべての変数をバインドしています。この特定のクエリは、配列から「WHERE」条件を取得します。

$w=array();
if ($pos!='') $w[]="PositionId=':pos'";
if ($country!='') $w[]="CountryId=':country'";
if ($current!='') $w[]="IsCurrent=':current'";
if ($c1stat!='') $w[]=":c1stat :c1comp ':c1val'";
if ($c2stat!='') $w[]=":c2stat :c2comp ':c2val'";
if ($c3stat!='') $w[]=":c3stat :c3comp ':c3val'";
if ($c4stat!='') $w[]=":c4stat :c4comp ':c4val'";
if (count($w)) $where="WHERE ".implode(' AND ',$w); else $where='';

$query="SELECT * FROM table $where";
$result = $pdo->prepare($query);
$result->bindParam(':pos', $pos);
$result->bindParam(':country', $country);
$result->bindParam(':iscurrent', $current);
$result->bindParam(':c1stat', $c1stat); $result->bindParam(':c1comp', $c1comp); $result->bindParam(':c1val', $c1val);
$result->bindParam(':c2stat', $c2stat); $result->bindParam(':c2comp', $c2comp); $result->bindParam(':c2val', $c2val);
$result->bindParam(':c3stat', $c3stat); $result->bindParam(':c3comp', $c3comp); $result->bindParam(':c3val', $c3val);
$result->bindParam(':c4stat', $c4stat); $result->bindParam(':c4comp', $c4comp); $result->bindParam(':c4val', $c4val);
$result->execute();

私はまだPDOとバインディング変数を理解しようとしているので、これを理解するのに苦労しています。

$ queryは正しく作成されています。たとえば、$country条件を持つWHEREステートメントは次のように生成されます。

SELECT * FROM skaterRScareer WHERE PositionId>='2' AND CountryId=':country'

では、なぜ変数がバインドされていないのですか?前もって感謝します!

4

1 に答える 1

1

データリテラル以外はバインドできません:

  • 文字列リテラル - わかりました
  • 数値リテラル - わかりました
  • 文字列リテラルの一部 - 失敗
  • 識別子 - 失敗
  • オペレーター - 失敗
  • 関数 - 失敗
  • 構文キーワード - 失敗
  • 任意のクエリ部分 - 失敗

だから - 悲しいかな!- 演算子または識別子のプレースホルダーはありません。代わりにホワイトリストに登録する必要があります。

コードには別の問題があります。実際にクエリにしたプレースホルダーのみの変数をバインドする必要があります

$c3statが空の場合:c3stat :c3comp :c3val、クエリにプレースホルダーはありません。したがって、対応する変数もバインドしないでください。

成功する

if ($c3val) {
    $w[] = "some field > :c3val";
    $values[":c3val"] = $c3val;
}

また、プレースホルダーを引用符で囲む必要もありません。

ホワイトリスト登録の例を次に示します。

$fields     = array("name","price","qty");
$operators  = array(">","<","=");
$fkey       = array_search($_GET['sort'],$orders));
$okey       = array_search($_GET['sort'],$orders));
if ($fkey !== FALSE && $okey !== FALSE) { 
    $field  = $fields[$fkey]; 
    $op     = $operators[$okey]; 
    $query .= "$field $op :placeholder";
}
于 2013-02-27T13:30:45.470 に答える