0

I have a problem with a form containing many dynamically created form elements with attached Server-Actions. After several postbacks I get a fatal memory exhausted error. The Serialize method of QForm consumes lots of megabyteds It seems the form state grows with every postback until it is so big, that serialize() throws the fatal memory exhausted error. Why is it growing? The amount of form elements is always the same...

Do have any advice?

thanx in advance,

Jan

  • Can you share the code in your configuration file? What version of QCubed are you using? It becomes helpful if you share the FormStateHandler that you are using and related configuration. – Vaibhav Kaushal Jan 08 '15 at 10:35
  • Hi Vaibhav, I have configured the FormStateHandler this way: public static $FormStateHandler = 'QSessionFormStateHandler'; I'm using QCubed Development Framework 2.1 Development Release In the configuration.php I've touched: define ('__DOCROOT__', '/var/www'); define ('__VIRTUAL_DIRECTORY__', ''); define ('__SUBDIRECTORY__', '/Raumplan2013'); I hope the information is sufficient. Thanks for your help, Jan – Jan Siepmann Jan 08 '15 at 12:00
  • You can check the answer I have posted and tell me if it solves the problem. – Vaibhav Kaushal Jan 10 '15 at 07:01

1 Answers1

0

I guess the problem is not that FormState grows. I think it's the session that grows. The thing is - as you go on doing postbacks or opening new pages, a new FormState is created. This FormState is saved in your PHP session (you are using QSessionFormStateHandler). At one point of time, the total size of all FormStates can get so big that PHP will not be able to handle that in session data. This happens because PHP has a setting which limits the amount of memory each script-run/request will consume (and that is a good thing).

Most of the times, PHP will complain about it by reporting that memory was exhausted. The reason this happens is: when you run/call a script, following things happen:

  1. PHP loads the user session information initially.
  2. PHP proceeds with Script execution.
  3. PHP executes the commands and goes on allocating more memory if needed.
  4. PHP ends execution

In your case, session data will keep on growing till it starts consuming enough memory that PHP cannot work allocate new variables within the set memory constraints (step 3 fails).

You have two solutions:

  1. Use another FormStateHandler. I would recommend using QDbBackedFormStateHandler to keep file system clean. Using another FormStateHandler makes sure that your session data is separate from your FormState data and all FormStates are saved individually (either in file or as a separate DB entry) and ensures that useless FormStates are not collected in your session.

  2. Increase PHP's per-script memory limit. This solution is not recommended and you should use it only as a temporary solution.

Also, there might be cases where you have declared a temporary variable in your form or one of the child controls which goes on growing. Consider this:

<?php
// We are inside the definition of a control/panel/form
$this->arrObj_TempEntries = array();

// ... using the above variable somewhere inside an event handler:
public function btnRefreshHandler($strFormId, $strControlId, $strParameter) {
    // Assume $arrObj_NewEntries is already populated with some objects
    foreach($arrObj_NewEntries as $objNewEntry){
        array_push($this->arrObj_TempEntries, $objNewEntry);
    }
}
// ... rest of the stuff
?>

In this case, the value of $this->arrObj_TempEntries will go on increasing because the old entries are not being cleared out and result in a very huge FormState and that will eventually crash the page. If the objects are controls, it is an even bigger issue.

I hope this helps.

Vaibhav Kaushal
  • 340
  • 1
  • 6
  • 16
  • Hello, I configured to use QDbBackedFormStateHandler but now it throws uses gzuncompress(): data error after 5 postbacks... Commenting out the compress/uncompress parts, it breaks while serializing. – Jan Siepmann Jan 12 '15 at 09:23
  • How large is your QForm? Approximately how many KBs? From PHP manual: `The function will return an error if the uncompressed data is more than 32768 times the length of the compressed input data or more than the optional parameter length.` – Vaibhav Kaushal Jan 12 '15 at 09:29
  • How can I determine the size of a QForm? I can confirm, that memory usage nearly doubles with each postback. As a try in the methods that fills the array, first I step through the array, and unset every entry, before I create new objects to add, but memory usageb still doubles. Seems that I'm freeing the array wrong way. CODE: foreach (arrControls as $control) {unset (control);} – Jan Siepmann Jan 12 '15 at 10:53
  • I have a memory limit of 128M, which is full after 4 callback after increasing it to 1024 temporarily fills it completely after appr. 30 callbacks. I'm clearing the array of controls before refilling them, but memory still fills up to fatal error occurs. I'm confused. – Jan Siepmann Jan 12 '15 at 14:19
  • memory usage doesn't double, but grows evrey postback by ca. 32Mb. Changing to DB based Handler stops after 2 Callbacks zu the data error (it seems that your suggestion with compress/uncompress is right) – Jan Siepmann Jan 12 '15 at 14:25
  • Try to do this instead: `$arrControls = array();` before adding in the new contents. The formstate will grow only if you are working if a class member variable (so it would probably be `$this->arrControls = array();`. Please check that. Also, it would be helpful if you could post the code of the panel/page where you are trying to do this. That would help a lot more. – Vaibhav Kaushal Jan 13 '15 at 11:52