2

I have a PHP script when the user submits a form which leads to an SQL query which, sometimes, exceeds the limit of memory PHP is entitled to use (which is 128M). The very specific line of code is the following : $rows = $db->fetchAll($select); (I'm using ZF1.12).

I have read everything that is possible to read on the subject, however I cannot figure out how to track the memory usage. I am aware of the memory_get_usage(true) and memory_get_peak_usage(true) functions which allow to monitor the memory PHP is currently using (but these give me values around ~13Mb which is far less than the limit of 128M). I have also tried to handle the fatal error with register_shutdown_function() but I would like to handle the probleme before the fatal error occurs.

I also don't want to increase the value via ini_set() nor .htaccess nor editing php.ini file.

Therefore, my question is : how can I monitor the memory PHP is currently using and do what I want to do before the limit is reached ?

PS : I have basically the same problem than this user but I don't want to catch Fatal Error, I want to do specific stuff before it occurs.

Community
  • 1
  • 1
D4V1D
  • 5,805
  • 3
  • 30
  • 65
  • 3
    Don't use `fetchAll()`, fetch one row at a time and process, then fetch the next.... that way you're only working with one row in memory at a time – Mark Baker Aug 19 '14 at 08:20
  • Thanks for your comment. What do you mean "fetch one row at a time and process"? If I'm replacing `fetchAll()` with `fetchRow()`, I end up with empty rows. – D4V1D Aug 19 '14 at 08:24
  • I don't understand how to get to next row. If I'm using `fetchRow()`, I have only one row in my result. – D4V1D Aug 19 '14 at 09:42
  • Ok, I have managed to retrieve the rows one by one. But the problem still remains as the user can create a large query which will get the memory limit reached. – D4V1D Aug 19 '14 at 12:16

3 Answers3

2

Try add limits to your query, and paginate it in loop. If you don't need objects try running "raw query" rather than using ORM.

If you will use loop to fetch results you can view memory usage with functions you already know.

Michał Fraś
  • 407
  • 7
  • 12
1

I ended up catching the fatal error with register_shutdown_function() and display a nice error page with layout.

D4V1D
  • 5,805
  • 3
  • 30
  • 65
1

A way of using less memory would be to use fetch() instead of fetchAll() and handle the results row by row. This eases the load and uses less memory:

Change: $rows = $db->fetchAll($select)

To:

while ($row = $db->fetch($select)) {
    echo $row; //Whatever you want to do with each row.
}

This is much more efficient than this (below) as you aren't trying to get all the data at once, you're handling it one result at a time:

$rows = $db->fetchAll($select)

foreach ($rows as $row) {
    echo $row; //Whatever you want to do with each row.
}
iswinky
  • 1,951
  • 3
  • 16
  • 47