2013-03-14 60 views
0

我一直在試圖找到MySQLi的解決方案,它沒有獲取數組函數,並且我找到了這個有趣的代碼位。你認爲這個代碼值得使用,沒有巨大的安全漏洞?MySQLi準備的結果數組

/* 
* 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); 

回答

2

雖然我看到在這個代碼中沒有「巨大的安全漏洞」,我不認爲它使用無論如何是值得的。 看,mysqli讓你無處可逃。 您對舊的mysql沒有這樣的問題,您在PDO中沒有這樣的問題。只有mysqli讓你的生活沒有理由變得複雜。

有時你可以通過使用get_result()解決這個問題,但它不能保證工作,甚至沒有必然PHP版本 - 這樣,你甚至不能告訴它提前。

更不用說你會遇到同樣的問題試圖綁定任意數量的佔位符查詢,甚至沒有半工作的解決方案!

因此,再次 - 而不是解決所有這些問題 - 爲什麼不使用一個明智的驅動程序,如PDO?
使用PDO,您可以使用熟悉的fetch(),不需要像上面的代碼那樣的柺杖。

另一種解決方案是避免使用本地預處理語句,並使用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 
+0

我寫我的代碼程序,因爲我覺得這樣更容易讀寫,尤其是學習你的代碼。在連接的OOP和其他代碼的程序之間跳轉會有什麼問題嗎?學習一點OOP比處理STMT更容易。 – Rujikin 2013-03-14 07:41:41

+0

如果您通過添加查詢處理的完整代碼來編輯您的問題,從定義查詢到獲取所有數據,我將能夠將其重寫爲PDO以向您顯示OOP樣式實際上是短10倍且更清晰可讀的寫。 – 2013-03-14 09:24:25

+0

如果我看到我的代碼的直接副本,學習會更容易。清理了代碼並更新了OP。提前致謝!! – Rujikin 2013-03-14 17:01:08