2

パラメータ化されたクエリhttps://github.com/colshrapnel/safemysqlに safemysql クラスを使用しています。通常、クエリを準備するときは、次のようになります。

$entries = $db->getAll("SELECT * FROM table WHERE age = ?i AND name = ?s ",$age,$name);

解析されるパラメータの総数が事前にわかっているこの種のクエリはかなり単純ですが、使用するパラメータの数がわからないクエリでスタックしているようです。検索フォーム:

私がやりたいことは、次のクエリをパラメータ化することです:

if($_POST['nameparts']){

    $parts = explode(' ',$_POST['nameparts']);

    foreach((array)$parts as $part){

        $q .= " AND ( `name` LIKE '%".$part."%' OR `firstname` LIKE '%".$part."%' ) ";

    }

    if($_POST['age'])
        $q .= " AND `age` = '".$_POST['age']."' ";

    $entries = $dbs->getAll("SELECT * FROM table WHERE 1 = 1 ".$q." ");

助言がありますか?

4

2 に答える 2

0

ユーザー提供のデータを使用する他の SQL クエリと同様に、これを真に安全な方法で処理する (または、本来の作業を延期する) には、placeholders を使用します

はい、その目標から始めて、それを見失わないようにしましょう- クエリ テキストに [user-supplied] データが含まれている場合、コードはsafemysql の(および安全な SQL の使用法) テナントの1 つに違反しており、以下は必ずしも当てはまりません。 !

[safemysql は] すべての動的クエリ部分 [または「ユーザー データのビット」] がプレースホルダーを介してクエリに入るために安全です。

解決策は、プレースホルダーとデータ配列を使用してクエリ テキストを動的に作成することですが、個別に作成することです。DQL (SQL 構文) とデータが混在することはありません。この分離(および下位レベルの保証) により、このアプローチに従った場合にSQL インジェクションが発生しないことが保証されます。

$data = array();
$q = "SELECT * FROM table WHERE 1 = 1 ";
if($_POST['nameparts']){
    $parts = explode(' ',$_POST['nameparts']);
    foreach((array)$parts as $part){            
        $q .= " AND (`name` LIKE ?s OR `firstname` LIKE ?s )";
        $data[] = '%' . $part . '%'; // add one for each replacement
        $data[] = '%' . $part . '%';
    }
    if($_POST['age']) {
        $q .= " AND `age` = ?i ";
        $data[] = $_POST['age'];
    }
}

これで、プレースホルダーとバインドするデータの配列を含むクエリ テキストができました。ヤッピー、あと少しです!次に、渡される配列を作成し、 parameters の配列を提供するメソッドを呼び出します

$params = array($q);
$params = array_merge($params, $data);

$entries = call_user_func_array(array($dbs, 'getAll'), $params);

そして、完成!

于 2014-04-23T23:51:30.750 に答える