2009-12-19 147 views
4

我爲我正在努力的一個項目創建了一個簡單的MySQLi類,使它更容易和更簡化,以便從數據庫中提取並推送到數據庫。 (也可以更熟悉PHP中的OOPPHP如何檢查MySQLi查詢是否需要關閉?

我不斷遇到的一個問題是努力使其儘可能高效。我嘗試關閉/釋放每個查詢/語句/結果集。在此過程中,我得到以下錯誤很多:

Warning: mysqli_result::close(): Couldn't fetch mysqli_result 

我覺得我得到了上述特別是因爲它試圖兩次關閉查詢連勝。

目前,我的課程可以做好準備和準備不足的陳述。所以我嘗試關閉2個地方的查詢/語句。如果我已經準備好一份聲明,我會在準備一份聲明時檢查一下,如果是這樣的話,我需要先關閉一個聲明,然後再做一個新聲明,最後再在課堂的析構函數中進行。

我意識到我可以關閉查詢/語句後,我拉和存儲的結果,但這似乎是混亂的原因有幾個。對於一個它刪除了重複使用準備好的語句的可能性。以及不允許我在運行後查詢某些查詢的相關信息,例如受影響的行等。

我知道我可以只爲每個查詢存儲這些信息,但不過它似乎正確的方式去解決這個問題將關閉/釋放查詢/語句,如果我需要做另一個,並且再次在腳本的末尾。

我已經試過環顧四周,閱讀我應該如何妥善處理這個任務,但我一直未能拿出任何東西。

所以我的問題是,有無論如何測試是否需要關閉或釋放查詢或語句?還是有更好的方法我應該試圖解決這個問題?

感謝您提供任何幫助或見解。

回答

1

我認爲如果結果集中沒有剩餘行,它應該自動關閉。因此,如果您遍歷整個結果集,則無需致電mysqli_result。但是,如果您只讀取包含約100行的結果集中的第一行,則應該關閉它。

+0

這似乎有點真實。我正在搞一些測試代碼,在執行完後執行'var_dump',取出後執行另一個測試代碼。他們打印相同的東西。當關閉後執行'var_dump'時,雖然你得到'屬性訪問不被允許',所以它顯然做了一些不同的事情。雖然如果它有什麼不同的效率明智的問題呢? 另外,當我將查詢限制爲1行(例如'LIMIT 0,1')時,它自己調用$ stmt-> fetch()不會關閉語句。雖然如果我做'while'循環和'echo'來確認只有一行,它會關閉它。 任何想法? – anomareh 2009-12-19 08:23:39

0

關閉它後,您可以將它設置爲null,然後在關閉它之前在析構函數中檢查null。

顯然,只有在確定已經完成使用時才需要清空已準備好的語句。

+0

這是否與關閉聲明相同?我真的沒有任何問題,讓事情可以這麼說。我絕不會確定它無緣無故關閉。我只是覺得,結束語句和釋放結果集是處理效率問題的正確方法。我知道,對於小事情來說,這可能不是最大的交易,但如果你的項目看到很多流量和擴展,那麼它很重要。如果你在這樣的條件下工作,那麼每一點效率都是重要的,那麼正確的做法是什麼? – anomareh 2009-12-19 08:31:24

0

您可以使用RAII或工廠類+引用計數來管理語句。這樣你就不需要明確地檢查什麼時候關閉任何東西。沒有看到你如何使用包裝器的細節,很難進入細節。 Objective-C的訪問模式也可能是使用的,這看起來是這樣的:

private function unsetStatement() { 
    if (isset($this->_stmt)) { 
     $this->_stmt->close(); 
     unset($this->_stmt); 
    } 
} 
function getStatement() { 
    return $this->_stmt; 
} 
function setStatement($stmt) { 
    $this->unsetStatement(); 
    $this->_stmt = $stmt; 
} 

你會永遠只能通過上述功能訪問聲明成員字段,甚至內部類。其實它看起來更像:

-(Statement *)statement { 
    return stmt_; 
} 
-(void)setStatement:(Statement *)stmt { 
    [stmt_ release]; 
    stmt = [stmt retain]; 
} 
0

這就是我用的。如果在聲明任何結果,我知道我需要釋放的結果:

if($stmt->num_rows() != 0) 
{ 
    $stmt->free_result(); 

    return FALSE; 
} 
0

如果mysqli的查詢結果已經null,你會得到以下警告在PHP 5:

Warning: myfunction(): Property access is not allowed yet in .... 

原則上一個可以處理這些案件有一個自定義錯誤處理或簡單地抑制警告/錯誤,即is_object($mysqliqresult) && @$mysqliqresult->free()

或者使用mysqli- statements經由prepare方法,而然後直接運行mysqlidblink->查詢,如下所示:

$query = "SELECT heptagon,hexagon FROM pentagon ORDER BY hexagon"; 
$stmt = $dblink->prepare($query); 
$stmt->execute(); 
!$stmt->field_count() && $stmt->free_result(); 

賈斯汀的建議是沒關係。