0

私は、フェッチ配列関数を持たないMySQLi stmtの解決策を見つけようとしていましたが、この興味深いコードに出くわしました。このコードは使用する価値があり、大きなセキュリティ上の欠陥はないと思いますか?

/*
 * Utility function to automatically bind columns from selects in prepared statements to
 * an array
 */
function bind_result_array($stmt)
{
    $meta = $stmt->result_metadata();
    $result = array();
    while ($field = $meta->fetch_field())
    {
        $result[$field->name] = NULL;
        $params[] = &$result[$field->name];
    }

    call_user_func_array(array($stmt, 'bind_result'), $params);
    return $result;
}

/**
 * Returns a copy of an array of references
 */
function getCopy($row)
{
    return array_map(create_function('$a', 'return $a;'), $row);
}

クレジット: http: //gunjanpatidar.wordpress.com/2010/10/03/bind_result-to-array-with-mysqli-prepared-statements/

常識による要求:

 $db = new PDO("mysql:host='localhost';dbname='testing'", 'username', 'password') or die('Could not connect to server');
$get_posts = mysqli_stmt_init($db);
mysqli_stmt_prepare($get_posts, 'select * from Chatposts where Chatid = ? and CPid > ? and Deleted = ? order by CPid desc limit ?');
mysqli_stmt_bind_param($get_posts, 'iiii', $chatroomid, $lastpost, $deleted, $limit);
mysqli_stmt_execute($get_posts);
mysqli_stmt_bind_result($get_posts, $newcolumn['ID'], $newcolumn['Chatid'], $newcolumn['Name'], $newcolumn['URL'], $newcolumn['Text'], $newcolumn['Datetime'], $newcolumn['IPaddress'], $newcolumn['Deleted']);
mysqli_stmt_store_result($get_posts);
mysqli_stmt_fetch($get_posts); // Trying to fetch array
mysqli_stmt_close($get_posts);
4

1 に答える 1

2

このコードには「巨大なセキュリティ上の欠陥」は見当たりませんが、とにかく使用する価値はないと思います。ほら、mysqliはどこからともなくあなたを悩ませます。古いmysqlではそのような問題はありませんでした。PDOではそのような問題はありません。mysqliだけが理由もなくあなたの人生を複雑にします。

を使用してこの問題を解決できる場合もありますがget_result()、動作が保証されておらず、PHPバージョンにバインドされていないため、事前に通知することもできません。

言うまでもなく、任意の数のプレースホルダーをクエリにバインドしようとすると同じ問題が発生し、半ば機能する解決策すらありません。

では、これらすべての問題を解決する代わりに、PDOのような賢明なドライバーを使用しないのはなぜですか?
PDOを使用すると、上記のコードのような松葉杖を使わずに、使い慣れたfetch()を箱から出してすぐに使用できます。

もう1つの解決策は、ネイティブのプリペアドステートメントの使用を控え、手動で解析された同等のステートメントを利用することです。これを使用すると、mysqli_query()古い良好なmysql_queryに似ています。
しかし、このアプローチは平均的なユーザーには複雑すぎるように思われるため、PDOを使用することをお勧めします。

これがPDOを使用したコードです

$dsn = "mysql:host=localhost;dbname=test;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => FALSE,
);
$pdo = new PDO($dsn,'root','', $opt);

$stm = $pdo->prepare('select * from Chatposts where Chatid = ? and CPid > ? and Deleted = ? order by CPid desc limit ?');
$stm->execute(array($chatroomid, $lastpost, $deleted, $limit));
$posts = $stm->fetchAll();
// now you have all requested posts in $posts array
于 2013-03-14T05:36:05.677 に答える