當前位置: 首頁> 最新文章列表> 怎樣通過mysqli::use_result函數有效避免PHP內存溢出問題?

怎樣通過mysqli::use_result函數有效避免PHP內存溢出問題?

gitbox 2025-08-27
<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 這部分代碼與文章內容無關,僅作示例佔位</span></span><span>

</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"歡迎閱讀本文,本文將探討如何使用mysqli::use_result函數避免PHP內存溢出問題。"</span></span><span>;

</span><span><span class="hljs-meta">?&gt;</span></span><span>

&lt;hr&gt;

</span><span><span class="hljs-meta">&lt;?php</span></span><span>
<span class="hljs-comment">/*
 * 怎樣通過mysqli::use_result函數有效避免PHP內存溢出問題?
 *
 * 在PHP中,使用MySQL數據庫時,經常會遇到查詢結果集較大時內存溢出的問題。特別是當使用mysqli擴展執行大結果集的查詢時,
 * 如果一次性將全部結果加載到內存,極易導致PHP內存耗盡,程序崩潰。
 *
 * mysqli提供了兩種獲取查詢結果的方式:store_result()和use_result()。
 * 
 * 1. store_result():
 *    默認方式,會將整個結果集一次性取回並緩存在客戶端內存中。
 *    對於大數據量,內存消耗非常大。
 * 
 * 2. use_result():
 *    採用"行級別"獲取方式,不會一次性把全部結果取回,而是通過網絡流式讀取數據。
 *    这样可以显著降低内存使用,避免內存溢出。
 *
 * 本文重點講解如何合理使用mysqli::use_result()避免內存溢出問題。
 */</span>

<span class="hljs-comment">/**
 * 使用mysqli::use_result的示例代碼
 */</span>
</span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">'localhost'</span></span><span>, </span><span><span class="hljs-string">'username'</span></span><span>, </span><span><span class="hljs-string">'password'</span></span><span>, </span><span><span class="hljs-string">'database'</span></span><span>);

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_errno) {
    </span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"連接失敗: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error);
}

</span><span><span class="hljs-comment">// 執行查詢</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">real_query</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM large_table"</span></span><span>)) {

    </span><span><span class="hljs-comment">// 通過use_result獲取結果集,避免一次性加載大量數據</span></span><span>
    </span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">use_result</span></span><span>();

    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$result</span></span><span>) {
        </span><span><span class="hljs-comment">// 逐行處理數據,減少內存佔用</span></span><span>
        </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$row</span></span><span> = </span><span><span class="hljs-variable">$result</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">fetch_assoc</span></span><span>()) {
            </span><span><span class="hljs-comment">// 處理每一行數據,例如輸出或寫入文件</span></span><span>
            </span><span><span class="hljs-comment">// echo $row['column_name'] . PHP_EOL;</span></span><span>
        }

        </span><span><span class="hljs-comment">// 釋放結果集資源</span></span><span>
        </span><span><span class="hljs-variable">$result</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">free</span></span><span>();
    } </span><span><span class="hljs-keyword">else</span></span><span> {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"獲取結果失敗:"</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error;
    }

} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"查詢失敗:"</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error;
}

</span><span><span class="hljs-comment">// 關閉連接</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">close</span></span><span>();

<span class="hljs-comment">/*
 * 詳細說明:
 *
 * 1. 流式讀取:
 *    使用use_result(),MySQL服務器不會一次性將結果發送給客戶端,而是保留連接,
 *    使客戶端逐行讀取。這樣避免了大量數據在內存中積累。
 * 
 * 2. 注意事項:
 *    - 在使用use_result()時,必須先讀取完所有結果或調用free(),才能執行新的查詢。
 *    - 不能混用store_result()和use_result(),避免連接阻塞。
 *    - 網絡連接必須保持,讀取過程不能中斷。
 *
 * 3. 性能對比:
 *    對比store_result(),use_result()犧牲了一定的性能(需要多次網絡交互),
 *    但显著减少了内存使用,適合大數據量場景。
 *
 * 4. 適用場景:
 *    - 查詢結果非常大,無法一次性加載。
 *    - 需要分塊處理結果,如寫入文件、分頁導出等。
 *
 * 總結:
 * 使用mysqli::use_result()實現流式查詢,是避免PHP內存溢出的一種有效策略。
 * 它允許開發者逐行獲取數據,降低內存峰值使用,從而增強程序穩定性。
 */</span>
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>