我有一个Zend表单,其中包含一个文件元素。
$this->addElement('file', 'image', array(
'label' => 'Upload Image:',
'destination' => APPLICATION_PATH . '/tmp/',
'validators' => array(
array('count', true, array(
'min' => 1,
'max' => 1,
'messages' => array(
Zend_Validate_File_Count::TOO_FEW =>
'You must upload an image file',
Zend_Validate_File_Count::TOO_MANY =>
'You can only upload one image file'))),
array('extension', true, array(
'extention' => 'jpg,png,gif',
'messages' => array(
Zend_Validate_File_Extension::NOT_FOUND =>
'The file has an invalid extention (jpg,png,gif only)',
Zend_Validate_File_Extension::FALSE_EXTENSION =>
'The file has an invalid extention (jpg,png,gif only)'))),
array('imageSize', true, array(
'minheight' => self::IMAGEHEIGHT,
'minwidth' => self::IMAGEWIDTH,
'maxheight' => self::IMAGEHEIGHT,
'maxwidth' => self::IMAGEWIDTH,
'messages' => array(
Zend_Validate_File_ImageSize::HEIGHT_TOO_BIG =>
'The image must be exactly ' . self::IMAGEHEIGHT . ' pixels tall',
Zend_Validate_File_ImageSize::HEIGHT_TOO_SMALL =>
'The image must be exactly ' . self::IMAGEHEIGHT . ' pixels tall',
Zend_Validate_File_ImageSize::WIDTH_TOO_BIG =>
'The image must be exactly ' . self::IMAGEWIDTH . ' pixels wide',
Zend_Validate_File_ImageSize::WIDTH_TOO_SMALL =>
'The image must be exactly ' . self::IMAGEWIDTH . ' pixels wide',
Zend_Validate_File_ImageSize::NOT_DETECTED =>
'The image dimensions cannot be detected',
Zend_Validate_File_ImageSize::NOT_READABLE =>
'The image dimensions cannot be read'))))
));
此文件元素设置为以后的代码段中不需要。当我提交没有附加文件的表单时,表单validtion返回false,当我使用getErrors()方法查找表单错误时,也没有报告错误。如果我提交带附件的表格,一切正常。
我一直在谷歌这个,但找不到答案。我希望有人可以解释为什么会这样,我正在使用ZF 1.11.11。
提前致谢。
加里
修改
以下是请求的更多代码示例。
这些是我用来验证表单的方法。我已将我用作验证错误的解决方法的代码标记为。
public function formValid(Array $params)
{
if (is_null($this->_form))
throw new Zend_Exception('You must first initialize the form');
$formValid = $this->_validateForm($this->_form, $params);
// Workaround for bug in validating file elements
if (!$formValid) {
if (!$this->_form->getMessages()) {
$formValid = true;
$this->_validValues = $this->_form->getValidValues($params);
}
}
if ($formValid) {
if ($this->_form instanceof Admin_Form_AddDirectSite ||
$this->_form instanceof Admin_Form_EditDirectSite) {
if (isset($this->_validValues['replaceImage'])) {
return $this->_form->getElement('image')->receive();
} else {
return true;
}
} elseif ($this->_form instanceof Admin_Form_PromoteDirectSite) {
$today = new Zend_Date();
$expires = new zend_date($this->_validValues['DirectSitesHighlighted']['toDate']);
if ($expires->isEarlier($today)) {
$this->_form->getSubForm('DirectSitesHighlighted')
->getElement('toDate')
->addError('The date must be in the future');
return false;
} else {
return true;
}
} else {
return true;
}
} else {
return false;
}
}
protected function _validateForm(Zend_Form $form, Array $params)
{
if ($form->isValid($params)) {
$this->_validValues = $form->getValidValues($params);
return true;
} else {
$this->_validValues = null;
return false;
}
}
这些是我用来初始化表单的函数,有两个表单类共享一个抽象类。
public function initAddForm()
{
$this->_form = new Admin_Form_AddDirectSite();
return $this;
}
public function initEditForm()
{
$this->_form = new Admin_Form_EditDirectSite();
return $this;
}
这些是三个表格类。
class Admin_Form_AddDirectSite extends Admin_Form_DirectSites_Abstract
{
public function init()
{
parent::init();
$this->setAction('/admin/direct-sites/add');
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'forms/addDirectSites.phtml'))
));
$this->getElement('image')->setRequired(true);
$this->addElement('hidden', 'replaceImage', array(
'required' => true,
'label' => 'Replace Image:',
'value' => 1,
'filters' => array('Int'),
));
}
}
class Admin_Form_EditDirectSite extends Admin_Form_DirectSites_Abstract
{
public function init()
{
parent::init();
$this->setAction('/admin/direct-sites/edit');
$this->setDecorators(array(
array('ViewScript', array('viewScript' => 'forms/editDirectSites.phtml'))
));
$this->getElement('image')->setRequired(false);
$this->addElement('checkbox', 'replaceImage', array(
'required' => false,
'label' => 'Replace Image:',
'checked' => false,
'attribs' => array(
'title' => 'Click to replace the image file'
),
'filters' => array('Int'),
'validators' => array(
array('Int', true, array(
'messages' => array(
Zend_Validate_Int::NOT_INT =>
'You must check to replace the image file'))))
));
$this->addElement('hidden', 'directSiteId', array(
'required' => false,
'vslue' => null
));
}
}
abstract class Admin_Form_DirectSites_Abstract extends Freedom_Zend_Form
{
/**
* Domain prefix http://www.
* @var integer
*/
const HTTPWWW = 1;
/**
* Domain prefix http://
* @var integer
*/
const HTTP = 2;
/**
* The image width in pixels
* @var integer
*/
const IMAGEWIDTH = 100;
/**
* The image height in pixels
* @var integer
*/
const IMAGEHEIGHT = 100;
/**
* Initialize the form
* @see Zend_Form::init()
*/
public function init()
{
$domainPrefix = array(
self::HTTPWWW => 'http://www.',
self::HTTP => 'http;//'
);
$genres = Model_Doctrine_GenresTable::getInstance()->getAllKeyPairs();
$artworkMediums = Model_Doctrine_ArtworkMediumsTable::getInstance()->getAllKeyPairs();
$this->setName('directSitesForm') // setup registration form
->setAttrib('id', 'directSitesForm')
->setMethod('post')
->setAttrib('class', 'directSitesForm')
->setEnctype(Zend_Form::ENCTYPE_MULTIPART);
$this->addElementPrefixPath('Freedom_Zend', 'Freedom/Zend'); // add element prefix path
$this->addPrefixPath('Freedom_Zend_Form', 'Freedom/Zend/Form'); // add form prefix path
$directSitesDescription = new Zend_Form_SubForm();
$directSitesTitle = new Zend_Form_SubForm();
$this->addElement('text', 'domainName', array(
'required' => true,
'label' => 'Domain Name:',
'attribs' => array(
'title' => 'Please enter the url of the site',
'size' => 20,
'maxlength' => 255
),
'filters' => array('StringTrim', 'StripTags', 'StripNewlines'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must specify the domain name"))),
array('StringLength', true, array(
'min' => 5,
'max' => 255,
'messages' => array(
Zend_Validate_StringLength::INVALID =>
'Your URL must be between 5 and 255 characters in length',
Zend_Validate_StringLength::TOO_LONG =>
'Your URL must not contain more than 255 characters',
Zend_Validate_StringLength::TOO_SHORT =>
'Your URL must contain more than 5 characters'))))
));
$this->addElement('radio', 'websitePrefix', array(
'required' => true,
'label' => 'Domain Prefix:',
'attribs' => array(
'title' => 'Please select the URL prefix for the domain name'
),
'multiOptions' => $domainPrefix,
'value' => self::HTTPWWW,
'filters' => array('int'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must select your agency's website URL",
Zend_Validate_NotEmpty::INVALID =>
"You must select your agency's website URL"))),
array('InArray', true, array(
'haystack' => array_keys($domainPrefix),
'messages' => array(
Zend_Validate_InArray::NOT_IN_ARRAY =>
"You must select your agency's website URL"))))
));
$directSitesTitle->addElement('text', 'title', array(
'required' => true,
'label' => 'Title:',
'attribs' => array(
'title' => 'Please enter the name of the site',
'size' => 20,
'maxlength' => 255
),
'filters' => array('StringTrim', 'StripTags', 'StripNewlines'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must specify the sites title"))),
array('StringLength', true, array(
'min' => 5,
'max' => 100,
'messages' => array(
Zend_Validate_StringLength::INVALID =>
'Your title must be between 5 and 100 characters in length',
Zend_Validate_StringLength::TOO_LONG =>
'Your title must not contain more than 100 characters',
Zend_Validate_StringLength::TOO_SHORT =>
'Your title must contain more than 5 characters'))))
));
$directSitesDescription->addElement('text', 'description', array(
'required' => true,
'label' => 'Description:',
'attribs' => array(
'title' => 'Please enter the description of the site',
'size' => 50,
'maxlength' => 100
),
'filters' => array('StringTrim', 'StripTags', 'StripNewlines'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must specify the sites description"))),
array('StringLength', true, array(
'min' => 5,
'max' => 100,
'messages' => array(
Zend_Validate_StringLength::INVALID =>
'Your sites description must be between 5 and 100 characters in length',
Zend_Validate_StringLength::TOO_LONG =>
'Your sites description must not contain more than 100 characters',
Zend_Validate_StringLength::TOO_SHORT =>
'Your sites description must contain more than 5 characters'))))
));
$this->addElement('file', 'image', array(
'label' => 'Upload Image:',
'destination' => APPLICATION_PATH . '/tmp/',
'validators' => array(
array('count', true, array(
'min' => 0,
'max' => 1,
'messages' => array(
Zend_Validate_File_Count::TOO_FEW =>
'You must upload an image file',
Zend_Validate_File_Count::TOO_MANY =>
'You can only upload one image file'))),
array('extension', true, array(
'extention' => 'jpg,png,gif',
'messages' => array(
Zend_Validate_File_Extension::NOT_FOUND =>
'The file has an invalid extention (jpg,png,gif only)',
Zend_Validate_File_Extension::FALSE_EXTENSION =>
'The file has an invalid extention (jpg,png,gif only)'))),
array('imageSize', true, array(
'minheight' => self::IMAGEHEIGHT,
'minwidth' => self::IMAGEWIDTH,
'maxheight' => self::IMAGEHEIGHT,
'maxwidth' => self::IMAGEWIDTH,
'messages' => array(
Zend_Validate_File_ImageSize::HEIGHT_TOO_BIG =>
'The image must be exactly ' . self::IMAGEHEIGHT . ' pixels tall',
Zend_Validate_File_ImageSize::HEIGHT_TOO_SMALL =>
'The image must be exactly ' . self::IMAGEHEIGHT . ' pixels tall',
Zend_Validate_File_ImageSize::WIDTH_TOO_BIG =>
'The image must be exactly ' . self::IMAGEWIDTH . ' pixels wide',
Zend_Validate_File_ImageSize::WIDTH_TOO_SMALL =>
'The image must be exactly ' . self::IMAGEWIDTH . ' pixels wide',
Zend_Validate_File_ImageSize::NOT_DETECTED =>
'The image dimensions cannot be detected',
Zend_Validate_File_ImageSize::NOT_READABLE =>
'The image dimensions cannot be read'))))
));
$this->addElement('multiCheckbox', 'Genres', array(
'required' => false,
'label' => 'Genres:',
'attribs' => array(
'title' => 'Please select the sites genres'
),
'multiOptions' => $genres,
'filters' => array('int'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must select the sites genres",
Zend_Validate_NotEmpty::INVALID =>
"You must select the sites genres"))),
array('InArray', true, array(
'haystack' => array_keys($genres),
'messages' => array(
Zend_Validate_InArray::NOT_IN_ARRAY =>
"You must select the sites genres"))))
));
$this->addElement('multiCheckbox', 'ArtworkMediums', array(
'required' => false,
'label' => 'Artwork Mediums:',
'attribs' => array(
'title' => 'Please select the sites artwork mediums'
),
'multiOptions' => $artworkMediums,
'filters' => array('int'),
'validators' => array(
array('NotEmpty', true, array(
'messages' => array(
Zend_Validate_NotEmpty::IS_EMPTY =>
"You must select the sites artwork mediums",
Zend_Validate_NotEmpty::INVALID =>
"You must select the sites artwork mediums"))),
array('InArray', true, array(
'haystack' => array_keys($artworkMediums),
'messages' => array(
Zend_Validate_InArray::NOT_IN_ARRAY =>
"You must select the sites artwork mediums"))))
));
$this->addElement('submit', 'save', array(
'label' => 'Save',
'attribs' => array(
'title' => 'Save')
));
$this->addSubForm($directSitesDescription, 'DirectSitesDescription')
->addSubForm($directSitesTitle, 'DirectSitesTitle');
}
}
答案 0 :(得分:1)
我只能看到你的'count'
验证器看起来有点不稳定,看起来你总是需要至少1个文件。至于为什么没有错误信息,我不知道
可以尝试设置'min' => 0
array('count', true, array(
'min' => 1,
'max' => 1,
'messages' => array(
Zend_Validate_File_Count::TOO_FEW =>
'You must upload an image file',
Zend_Validate_File_Count::TOO_MANY =>
'You can only upload one image file'))),
以下是Zend_Validate_File_Count构造函数的API,请参阅ZF 1.11 API处的整个API
__ construct(integer | array | \ Zend_Config $ options):void设置验证器选项
Min限制文件计数,当与max = null一起使用时,它是最大值 文件计数它还接受一个键为'min'和'max'的数组 $ options是一个整数,它将被用作最大文件数As Array 接受以下键:'min':最小文件数'max':最大值 filecount参数名称类型描述 $ options integer | array | \ Zend_Config适配器选项
答案 1 :(得分:1)
仔细检查以确保
enctype='multipart/form-data'
包含在html表单元素中。我花了两个小时同样的问题。事实证明这是我的问题。
答案 2 :(得分:0)
RockyFord是正确的,您应该将min
验证程序的Count
值设置为0。
即使不需要元素,当值不为空时,仍会处理其验证器。文件元素与计数验证器的工作方式略有不同。如果指定min
大于0,则仍需要上传许多文件。
请在关闭所需标志的位置尝试以下代码。另外,我们将Count验证器设置为至少需要0个文件。
$form->getElement('image')
->setRequired(false)
->getValidator('count')
->setMin(0);
我对此进行了测试并且有效。如果我没有将min设置为0,表单将无法验证,但是,我会看到一条错误消息,显示You must upload an image file
。也许您的装饰器没有在File元素上显示错误?
答案 3 :(得分:0)
ZF 1.11 一个更简单的解决方案是在提交表单时删除元素:
$upload = new Zend_File_Transfer();
$files = $upload->getFileInfo();
if(empty($files))
{
$form->removeElement('image_name');
}
else
{
$form->image_name->receive();
}
if($form->isValid($_POST))
{
$formData = $form->getValues();
}
答案 4 :(得分:0)
在类isValid
派生的类中覆盖方法Zend_Form
。
/**
* Class Custom_Form
*/
class Custom_Form extends Zend_Form
{
// [...]
/**
* Validate the form
*
* @param array $data
* @throws Zend_Form_Exception
* @return bool
*/
public function isValid($data)
{
/** @var Zend_Form_Element_File $file */
$file = $this->getElement('file');
/**
* Remember the validators we set before
*/
$validators = $file->getValidators();
/**
* Remove validators if field is empty
*/
if (empty($_FILES['file']['name'])) {
$file->removeValidator('Extension');
}
/**
* Run validation
*/
$isValid = parent::isValid($data);
/**
* Set back the original validators after validation
*/
$file->setValidators($validators);
return $isValid;
}
// [...]
}