【问题标题】:Symfony custom filename for uploaded image files上传图像文件的 Symfony 自定义文件名
【发布时间】:2018-02-21 23:30:21
【问题描述】:

我知道 VichUpload 和命名器,但我必须面对两种不同的文件上传,并且我需要特殊的命名约定,而当前的 VichUpload 文档无法获得这些约定。

第一个文件上传用于一个名为“学校”的实体,该实体管理每所学校及其徽标。所以,作为网络根目录'../web/files/schools/',然后我会使用school_id,然后是带有上传文件名的'logo'文件夹,所以它可能是'../web/files/学校/000001/logo.png'。

然后,第二个实体是 'students' 来存储照片,带有来自 School 实体的 school_id 外键。因此,生成的文件名将取决于学校 ID 和学生 ID,作为学生 '../web/files/schools//students/.[jpg|png]' 的根, student_id 左侧有六个零填充。

这是config.yml 中关于此的部分(更新信息):

    school_image:
        upload_destination: "../web/files/images/schools"
        uri_prefix: "/files/images/schools"
        directory_namer:
            service: vich_uploader.directory_namer_subdir
            options: { property: 'schoolDirectory', chars_per_dir: 6, dirs: 1 }
        namer:
            service: vich_uploader.namer_property
            options: { property: 'idSlug' }
        inject_on_load:     true
        delete_on_update:   true
        delete_on_remove:   true
    student_image:
        upload_destination: "../web/files/images/schools"
        uri_prefix: "/files/images/schools"
        directory_namer:
            service: vich_uploader.directory_namer_subdir
            options: { property: 'userDirectory', chars_per_dir: 6, dirs: 1 }
        namer:
            service: vich_uploader.namer_property
            options: { property: 'userImage'}
        inject_on_load:     true
        delete_on_update:   true
        delete_on_remove:   true

在学校实体中(可能使用肮脏的解决方法):

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Vich\UploadableField(mapping="school_image", fileNameProperty="imageName")
 *
 * @Assert\Image()
 *
 * @var File
 */
private $imageFile;

public function getIdSlug()
{
    $slug = sprintf("%06d", $this->getId());
    return $slug;
}

public function getSchoolDirectory()
{
    $slug = sprintf("%06d", $this->getId());
    return $slug;
}

在学生实体中(不工作,如下所述):

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Vich\UploadableField(mapping="student_image", fileNameProperty="imageName")
 *
 * @Assert\Image()
 *
 * @var File
 */
private $imageFile;

public function getUserDirectory()
{
    $schoolDir = $this->getSchool()->getSchoolDirectory();
    $dir = $schoolDir.'/students/'.sprintf("%06d", $this->getId());
    return $dir;
}

public function getUserImage()
{
    return $this->getUsername() . $this->getImageFile()->getExtension();
}

这种同时使用“namer”和“directory_namer”的设置似乎忽略了 directory_namer 中的路径,并使用路径“/.ext”而不是“/.ext”。如果我更改 getUserImage() 函数并预先添加 getUserDirectory() 的结果(即,数据库存储“/.ext”而不仅仅是“.ext”),则“ " 路径被忽略,只创建 ".ext"。

由于 upload_prefix 和 uri_destination 似乎不处理可变数据,我如何设置命名器或其他任何东西来为这两种情况获取此路径?

顺便说一句,根据vendor 文件夹中捆绑的composer.json,我使用的是Symfony 3.1,并且composer 不允许更新超出“1.7.x-dev”的内容。 如果您发现它应该与此设置一起使用并且可能的解决方案是升级,我会感谢指出解决问题的特定文件,以便我可以手动粘贴任何错误。

解决方案:

问题在于,由于“旧”版本,缺少 directory_namer 类 PropertyDirectoryNamer,其服务名称为 vich_uploader.namer_directory_property,而不是 vich_uploader.directory_namer_subdir,这是一个错误的类。我复制了这个类并在namer.xml文件中注册了它,然后得到了预期的结果。现在我将尝试将其标记为已解决。

【问题讨论】:

    标签: image symfony upload filenames


    【解决方案1】:

    您需要创建实现的自定义目录命名器类

    Vich\UploaderBundle\Naming\DirectoryNamerInterface
    

    例如:

    namespace App\Services;
    
    use Vich\UploaderBundle\Mapping\PropertyMapping;
    
    class SchoolDirectoryNamer implements DirectoryNamerInterface
    {
        public function directoryName($object, PropertyMapping $mapping): string
        {
            // do what you want with $object and $mapping 
            $dir = '';
    
            return $dir;
        }
    }
    

    然后,将其作为服务。

    services:
        # ...
        app.directory_namer.school:
            class: App\Services\SchoolDirectoryNamer
    

    最后一步是配置 vich_uploader

    vich_uploader:
        # ...
        mappings:
            school:
                upload_destination: school_image
                directory_namer:    app.directory_namer.school
            student:
                upload_destination: student_image
                directory_namer:    app.directory_namer.student
    

    来源:VichUploaderBundle - How To Create a Custom Directory Namer

    【讨论】:

    • 感谢您的回复。我在原始帖子中添加了更多信息。
    • 我已经使用 symfony 3.4.6 创建了一个测试用例,并且通过这个设置得到了相同的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    相关资源
    最近更新 更多