Ха-ха, это случилось со мной тоже! И Я пожаловался на это разработчикам, и они проигнорировали меня .
Когда вы вызываете result (), он будет перебирать все возможные результаты и сохранять запись в массивном внутреннем массиве. Смотрите system/database/DB_result.php
цикл while в конце result_object () и result_array ()
Есть три способа исправить это.
Простой способ:
LIMIT
(или TOP
в MSSQL ) ваши результаты в запросе SQL.
SELECT TOP(100) * FROM Table
ОБНОВЛЕНО небуферизованным способом:
Используйте функцию unbuffered_row()
, которая была введена 2 года спустя после того, как был задан этот вопрос.
$query = $this->db->query($sql);
// not $query->result() because that loads everything into an internal array.
// and not $query->first_row() because it does the same thing (as of 2013-04-02)
while ($record = $query->unbuffered_row('array')) {
// code...
}
Сложный путь:
Используйте правильный объект результата, который использует итераторы PHP5 (что не нравится разработчикам, поскольку он исключает php4). Сделайте что-то подобное в вашем файле DB_result.php:
-class CI_DB_result {
+class CI_DB_result implements Iterator {
var $conn_id = NULL;
var $result_id = NULL;
var $result_array = array();
var $result_object = array();
- var $current_row = 0;
+ var $current_row = -1;
var $num_rows = 0;
var $row_data = NULL;
+ var $valid = FALSE;
/**
function _fetch_assoc() { return array(); }
function _fetch_object() { return array(); }
+ /**
+ * Iterator implemented functions
+ * http://us2.php.net/manual/en/class.iterator.php
+ */
+
+ /**
+ * Rewind the database back to the first record
+ *
+ */
+ function rewind()
+ {
+ if ($this->result_id !== FALSE AND $this->num_rows() != 0) {
+ $this->_data_seek(0);
+ $this->valid = TRUE;
+ $this->current_row = -1;
+ }
+ }
+
+ /**
+ * Return the current row record.
+ *
+ */
+ function current()
+ {
+ if ($this->current_row == -1) {
+ $this->next();
+ }
+ return $this->row_data;
+ }
+
+ /**
+ * The current row number from the result
+ *
+ */
+ function key()
+ {
+ return $this->current_row;
+ }
+
+ /**
+ * Go to the next result.
+ *
+ */
+ function next()
+ {
+ $this->row_data = $this->_fetch_object();
+ if ($this->row_data) {
+ $this->current_row++;
+ if (!$this->valid)
+ $this->valid = TRUE;
+ return TRUE;
+ } else {
+ $this->valid = FALSE;
+ return FALSE;
+ }
+ }
+
+ /**
+ * Is the current_row really a record?
+ *
+ */
+ function valid()
+ {
+ return $this->valid;
+ }
+
}
// END DB_result class
Затем, чтобы использовать его, вместо вызова $query->result()
вы используете только объект без ->result()
на конце, как $query
. И все внутреннее содержимое CI все еще работает с result()
.
$query = $this->db->query($sql);
foreach ($query as $record) { // not $query->result() because that loads everything into an internal array.
// code...
}
Кстати, у моего кода Iterator, работающего с их кодом, есть некоторые логические проблемы со всем -1, так что не используйте одновременно $query->result()
и $query
для одного и того же объекта. Если кто-то хочет это исправить, вы великолепны.