I found that CI framework has memory leak in collection of functions which are described in “Generating Query Results” of CI manual. Those functions need to get access to rows in database result object.
The source code of those function can be found in file: $CI_DIR\system\database\DB_result.php.
Investigate shows that every functions there based on 2 main functions: result_object(), result_array().
The difference between them is type of container which they uses to store values, the first function uses object, second uses associative array. So look at the one will enough to understand the problem and where is source of headache there.
function result_array
()
{
if (count($this->
result_array) >
0)
{
return $this->
result_array;
}
// In the event that query caching is on the result_id variable
// will return FALSE since there isn’t a valid SQL resource so
// we’ll simply return an empty array.
if ($this->result_id === FALSE OR $this->num_rows() == 0)
{
return array();
}
$this->_data_seek(0);
while ($row = $this->_fetch_assoc())
{
$this->result_array[] = $row;
}
return $this->result_array;
}
Have you guessed it already?
The problem in cycle. In where we walk trough all items, keep every in container array and then return this array. Obviously, if database result has enough many records, as I had in my case, it will work till we will have free memory, then we will get fatal error something like this:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 33 bytes) in /var/www/html/tagnet/system/database/DB_driver.php on line 173
It means that our memory finished. My query had returned approximate 300,000 records, so I suppose it’s not extraordinary case.
Why has authors used such solutions there? I think they would like to use foreach construction very much for a walking in result.
I did not find in google how people solve this problem, may be I was not lucky in my searches. But I found description of the similar problem here. But this problem was fixed by authors of CI.
Bay the way, how I solve this problem?
foreach($result->result_array() as $row) {
…
}
while ($row = $result->_fetch_assoc()) {
…
}
Of course it’s not good that I have used “private” member of class CI_DB_result, but I still use CI API for fetching rows and don’t use database dependence functions.