我的应用程序有一个Web表单,用于验证和保存用户信息,总计近30个字段。还有一个CSV上传选项,我试图重新使用我创建的Form和InputFilter类。我遇到了两个问题。当我重复实例化表单时,我的内存消耗会通过顶部并最终因内存不足而崩溃。
foreach ($CSVdata as $data) {
$form = new LocationForm();
$filter = new LocationFilter();
$form->setInputFilter($filter->getInputFilter());
$form->setData($data);
if (!$form->isValid()) {
$messages[] = $form->getMessages();
} else {
$db->save($form->getData(\Zend\Form\FormInterface::VALUES_AS_ARRAY));
}
}
我尝试将代码放在函数中并在循环中调用函数,理论上在函数退出后对象超出范围时释放内存但我仍然看到内存每次调用大约300k,直到它运行记忆力不足。
所以我尝试仅将表单对象实例化一次,并在循环中调用$ form-> setData()。这解决了内存问题,但是现在当我尝试验证行并且元素验证失败时,为该行返回的messages数组包含每个前一行的每个失败元素。例如:
$data[0] = array(a, b, c); // element 'b' fails validation.
$messages[0] says 'b' failed validation.
$data[1] = array(a, b, c); // element 'c' fails validation.
$messages[1] says BOTH 'b' and 'c' failed validation even though 'b' was actually valid!
我认为这是有意义的,因为我重复使用相同的表单对象。所以我的问题是,有没有办法重置"每次传递后的表单对象或输入过滤器,而不重新实例化任何对象?它似乎记得或不重新初始化消息数组,我无法找到执行此功能的函数。或者我是以完全错误的方式来做这件事的?我非常喜欢ZF2中的表单验证和过滤,但似乎没有人使用它来验证大型数据集(或者我只是在搜索错误的东西)。
答案 0 :(得分:0)
您可以在LocationForm
课程内的任何位置使用以下代码重置消息。
$this->messages = array();
如果你需要在循环中执行此操作,可以在LocationForm
中创建一个包含此行代码的公共函数。例如:
class LocationForm {
public function resetForm() {
$this->messages = array();
}
}
然后在你的循环中,只需致电$form->resetForm();
答案 1 :(得分:0)
在深入了解Zend Form元素和方法之后,我终于弄明白了。在调用$ form-> setData()之前运行以下代码会清除前一循环迭代中的任何错误消息:
$messages = $form->getInputFilter()->getMessages();
if (! empty($messages)) {
foreach ($messages as $elementName => $validatorName) {
$form->get($elementName)->setMessages(array($validatorName => null));
}
}