来自后端应用程序的用户可以上传文件并将其发布到前端。使用sfWidgetFormInputFile和sfValidatorFile,我想保留原始文件名而不是随机字符串的默认功能(即Meaningful_filename.docx而不是a4b25e9f48cfb6268f34b691fc18cd76fefe96b5.docx - 数字可以附加到重复的名称上)。这在用户下载多个文件并且无法区分文件名的情况下非常有用。
$this->widgetSchema['file_name'] = new sfWidgetFormInputFile(array('label' => 'File'));
$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required' => true,
'path' => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR,
'mime_types' => array('application/msword',
'application/vnd.ms-word',
'application/msword',
'application/msword; charset=binary')
), array(
'invalid' => 'Invalid file.',
'required' => 'Select a file to upload.',
'mime_types' => 'The file must be a supported type.'
));
sfWidgetFormInputFile小部件中是否有本机功能,还是有其他解决方案?
答案 0 :(得分:22)
您可以致电$form["file_name"]->getValue()
获取该文件。这为您提供了类sfValidatedFile
的对象,您可以在其中调用方法getOriginalName()
。
要定义文件的保存方式,您可以执行以下操作:
sfValidatorFile
类接受sfValidatedFile
类要使用的选项:
validated_file_class:管理已清理的上载文件的类的名称(可选)
sfValidatedFile
类有一个调用方法save
的方法generateFileName
。对此类进行子类化并覆盖此方法:
class CustomValidatedFile extends sfValidatedFile {
/**
* Generates a random filename for the current file.
*
* @return string A random name to represent the current file
*/
public function generateFilename()
{
return 'foo bar'// your custom generated file name;
}
}
以下是原始类的功能:
public function generateFilename()
{
return sha1($this->getOriginalName().rand(11111, 99999)).$this->getExtension($this->getOriginalExtension());
}
然后以这种方式设置验证器:
$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required' => true,
'path' => 'yourpath',
'validated_file_class' => 'CustomValidatedFile',
'mime_types' => array('application/msword',
'application/vnd.ms-word',
'application/msword',
'application/msword; charset=binary')
),
array('invalid' => 'Invalid file.',
'required' => 'Select a file to upload.',
'mime_types' => 'The file must be a supported type.')
);
希望有所帮助!
答案 1 :(得分:5)
经过一些研究:
虽然您可以扩展sfValidatedFile并覆盖generateFilename,但我发现sfFormPropel会根据模型的列名来检查是否存在方法来命名文件。
来自symfony / plugins / sfPropelPlugin / lib /表格第292行:
$method = sprintf('generate%sFilename', $column);
if (null !== $filename)
{
return $file->save($filename);
}
else if (method_exists($this, $method))
{
return $file->save($this->$method($file));
}
因此,如果您的列名为file_name,则该方法会在表单类中查找generateFileNameFilename的存在。这样,您只需要向表单类添加一个方法,而不是扩展sfValidatedFile小部件。例如,我的函数使用原始名称,如果不采用,否则附加一个序号(一种方法是递归检查生成的文件名):
public function generateFileNameFilename($file = null)
{
if (null === $file) {
// use a random filename instead
return null;
}
if (file_exists($file->getpath().$file->getOriginalName())) {
return $this->appendToName($file);
}
return $file->getOriginalName();
}
public function appendToName($file, $index = 0)
{
$newname = pathinfo($file->getOriginalName(), PATHINFO_FILENAME).$index.$file->getExtension();
if (file_exists($file->getpath().$newname)) {
return $this->appendToName($file, ++$index);
} else {
return $newname;
}
}
我无法在symfony API中找到这个记录,这就是为什么需要搜索代码库来查找的原因。如果您在许多地方使用此方法,那么扩展sfValidatedFile也可能是一个不错的选择。
答案 2 :(得分:1)
根据Symfony文档“sfValidatorFile验证器验证上传的文件。验证器将上传的文件转换为sfValidatedFile类的实例,如果已设置,则转换为validated_file_class选项的实例。” (来源:http://www.symfony-project.org/forms/1_4/en/B-Validators#chapter_b_sub_sfvalidatorfile)
虽然sfValidatedFile类开箱即用重命名文件,但您可以通过将validated_file_class设置为自定义类并扩展sfValidatedFile来覆盖此函数。
在自定义验证的文件类中,将自定义文件名传递给save()方法。 “如果你没有传递文件名,它将由generateFilename方法生成。” (资源: http://www.symfony-project.org/api/1_4/sfValidatedFile#method_save)
这是你可以做到的一种方式(来源:http://forum.symfony-project.org/index.php/m/90887/#msg_90887)...
自定义验证文件类:
// lib/validator/myValidatedFile.php
class myValidatedFile extends sfValidatedFile {
private $savedFilename = null;
// Override sfValidatedFile's save method
public function save($file = null, $fileMode = 0666, $create = true, $dirMode = 0777) {
// This makes sure we use only one savedFilename (it will be the first)
if ($this->savedFilename === null) $this->savedFilename = $file;
// Let the original save method do its magic :)
return parent::save($this->savedFilename, $fileMode, $create, $dirMode);
}
}
确保为sfWidgetFormInputFile设置'validated_file_class' => 'myValidatedFile'
。并在Form的保存方法中设置文件名的逻辑。