CodeIgniter 3.1.7:unbuffered_row()返回NULL但row()正常,CSV导出仅表头
row() Works But unbuffered_row() Doesn't in CodeIgniter's CSV Export Hey there, let's dig into why you're hitting this issue with CodeIgniter's csv_from_result() method returning only headers—this is almost always related to how CodeIgniter handles buffered vs. unbuffered result sets, not necessarily a bug. Here's a breakdown of the key factors:
1. Result Set Pointer Position
The most common culprit is that your query result set's internal pointer has already been moved to the end before csv_from_result() calls unbuffered_row().
unbuffered_row()works by fetching the next row from the result set and advancing the pointer immediately. If you ran any other methods on the result (likeresult(),row(), or evennum_rows()) before callingcsv_from_result(), the pointer would already be at the end of the dataset, sounbuffered_row()returnsNULLevery time.row()(in most standard usage) relies on CodeIgniter's default buffered result set, which stores the full dataset in memory. Even if the pointer was moved, you can implicitly reset it or traverse the dataset again—somethingunbuffered_row()can't do once it's started reading rows.
2. Buffered vs. Unbuffered Query Differences
CodeIgniter has two distinct result set types:
- Buffered results (default): The entire result set loads into memory right after the query runs. You can traverse it multiple times, reset the pointer with
data_seek(0), and use methods likenum_rows()without issues. - Unbuffered results: Rows are fetched one at a time directly from the database, with no full dataset stored in memory. This is great for large datasets but means you can't go back to previous rows once you've fetched them.
unbuffered_row() is purpose-built for unbuffered queries. If you're using a buffered query (the default), it should behave similarly to row()—but if the pointer was already shifted by a prior operation, it'll fail silently. Conversely, if you accidentally initialized an unbuffered query and read rows elsewhere first, unbuffered_row() will have nothing left to fetch.
3. Minor Version-Specific Quirks
While it's not a widespread "bug," some older CodeIgniter versions had inconsistencies in how unbuffered_row() handled buffered result sets. For example, certain releases didn't correctly reset the pointer for buffered datasets when unbuffered_row() was called, whereas row() handled this logic more reliably.
How to Fix & Verify
- Check for pre-existing result reads: Make sure you're not calling any other result methods (like
result(),row(), or even debugging withprint_r($result)) on the query result before passing it tocsv_from_result(). - Reset the pointer explicitly: If you must read the result before exporting, reset the pointer to the start with
$result->data_seek(0)before callingcsv_from_result(). Note this only works for buffered result sets. - Force a buffered query: If you're using an unbuffered query (by passing
TRUEas the third parameter to$this->db->query()), remove that parameter to use the default buffered mode and test ifunbuffered_row()starts working. - Update CodeIgniter: If you're on an older version, upgrading to the latest stable release might resolve any minor inconsistencies with
unbuffered_row().
In most cases, this isn't a CodeIgniter bug—it's just a mismatch between how you're handling the result set and how unbuffered_row() is designed to operate.
内容的提问来源于stack exchange,提问作者pbarney

