tags:

views:

1179

answers:

4

Most of my PHP apps have an ob_start at the beginning, runs through all the code, and then outputs the content, sometimes with some modifications, after everything is done.

ob_start()
//Business Logic, etc
header->output();
echo apply_post_filter(ob_get_clean());
footer->output();

This ensures that PHP errors get displayed within the content part of the website, and that errors don't interfere with header and session_* calls.

My only problem is that with some large pages PHP runs out of memory. How do I stop this from happening?

Some ideas:

  1. Write all of the buffered content to a temporary file and output that.
  2. When the buffers reaches a certain size, output it. Although this might interfere with the post filter.
  3. Raise the memory limit (thanx @troelskn).

Whats the drawbacks on each of these approaches? Especially raising the memory limit?

+4  A: 

Can't you raise the memory limit? Sounds like the best solution to me.

Edit: Obviously, raising the memory limit just because a script tops out should raise some red flags, but it sounds to me like this is a legitimate case - eg. the script is actually producing rather large chunks of output. As such, you have to store the output somewhere, and memory seems to be the best pick, for both performance and convenience reasons.

I should note also that the memory limit setting is just that - a limit. Scripts that don't consume much memory, won't consume more just because you raise the limit. The main reason for its existence, is to prevent misbehaving/buggy scripts from taking down the entire server. This is something that is important if you have a lot of amateurs hacking away on a shared host (Something PHP has been used a lot for). So if this is your own server, or at least you generally know what you're doing, there isn't really any benefit from having a low memory-limit.

troelskn
I think that's the best approach as well.
pd
I tried that, but something in me kicks at raising the memory limit. Any drawbacks to raising the mem limit?
Jrgns
+1  A: 

You should raise the memory limit before anything, especially if your only other solution is to go through a temporary file.

There's all kinds of downsides to using temporary files (mainly, it's slower), and if you really need a way to store the buffer before outputing it, Go look for memcached or APC cache. This would let you do roughly the same as a file, except you have the fast access of RAM.

I must say this is a terrible idea overall, though. If the buffer currently doesn't work right, there's likely something you could build differently in order to make your site work better.

I GIVE TERRIBLE ADVICE
+1  A: 

If the php errors are the only reason for buffering output consider using set_error_handler. With this function you can define a custom callback for errors in your script. Use it to save the messages somewhere and print them later.

http://www.php.net/set_error_handler

okoman
It's not just for the errors. Notice the apply_post_filter function that changes the output.
Jrgns
A: 

For you to run out of memory due to output you must have a huge amount of data going out or very low memory limits. 4 or so years ago a memory limit of 8mb was common enough, and reasonable. But with the switch to using objects and just better coding styles in general the memory usage of scripts that I've come across have increased.

Hrm... where is it that your scripts run out of memory? If it's always in your output filtering functions maybe they just need to be optimised? memory_get_usage() will return the amount of memory in use by your script at that point.

What's the current memory limit you're running at? Are you running in a shared environment? At the moment I've got memory limits between 64 and 128 depending on the server.

If it's only a specific subset of scripts you want to increase the limit for then you can do it per script:

ini_set('memory_limit','64M');

If you want no limit for the script you can set this to -1

J.D. Fitz.Gerald
The server is a production server for a few, very large, web apps. I think the mem limit is 128Mg. I strike the limit when I load a VERY large PHP template file into the buffer.
Jrgns