在 Symfony 4 应用程序中,您将用户上传的内容存储在哪里?

Where do you store user uploaded content within a Symfony 4 application?

我的站点中有一个部分,用户可以在其中上传自己的个人资料图片,这些图片存储在输出目录中并在数据库中进行跟踪,如下所示:

    $form = $this->createForm(ProfileUpdateForm::class);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid())
    {
        $user = $this->getUser();
        $firstname = $form->get('firstname')->getData();
        $lastname = $form->get('lastname')->getData();
        $picture = $form->get('profilepicture')->getData();

        if($picture == null)
        {
            $user
            ->setFirstName($firstname)
            ->setLastName($lastname);
        }
        else
        {
            $originalFilename = pathinfo($picture->getClientOriginalName(), PATHINFO_FILENAME);
            // this is needed to safely include the file name as part of the URL
            $safeFilename = strtolower(str_replace(' ', '', $originalFilename));
            $newFilename = $safeFilename.'-'.uniqid().'.'.$picture->guessExtension();

            try {
                $picture->move(
                    'build/images/user_profiles/',
                    $newFilename
                );
            } catch (FileException $e) {
                $this->addFlash("error", "Something happened with the file upload, try again.");
                return $this->redirect($request->getUri());
            }

            // updates the 'picture' property to store the image file name
            // instead of its contents
            $user
            ->setProfilePicture($newFilename)
            ->setFirstName($firstname)
            ->setLastName($lastname);
        }

        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        $this->addFlash("success", "Your profile was updated!");
        return $this->redirectToRoute('account');
    }

    return $this->render('account/profile.html.twig', [
        'profileform' => $form->createView()
    ]);

我发现的那个问题是,每次我编译我的(本地)项目时,图像都会被删除(因为 public/build 目录是通过删除和重新创建构建的)。

如果我没记错的话,部署不也是这样吗?如果是这样,这是上传图片的正确方法吗?正确的做法是什么?

我不确定为什么,但您的 public/ 目录不应该被删除。
如果您使用的是 Webpack Encore,那么 public/build/ 内容会在您编译资产时被删除并重新创建。但不是 public/ 本身。

对于上传,我们创建 public/upload/ 目录。
然后,大多数时候,我们会设置一些全局变量,这样我们就可以只保存文件名。

config/packages/twig.yaml 中 Twig 的全局变量 "root" 将在您的 public/ 目录中

twig:
    globals:
        app_ul_avatar: '/upload/avatar/'
        app_ul_document: '/upload/document/'

以及 config/services.yaml

中控制器、存储库等的全局变量
parameters:
    app_ul_avatar: '%kernel.root_dir%/../public/upload/avatar/'
    app_ul_document: '%kernel.root_dir%/../public/upload/document/'

这很方便,因为正如我刚才所说,您只需将文件名保存在数据库中。

这意味着,如果你有一个 public/upload/img/ 文件夹,并且还想生成缩略图,你可以创建 public/upload/img/thumbnail/ 并且你的数据库中没有任何改变,你也不必保存一条额外的路径。

只需创建一个新的全局 app_ul_img_thumbnail,就大功告成了。

那么你所要做的就是在你需要的时候调用你的全局变量,并与文件名联系:

在 Twig 中:

{{ app_ul_avatar~dbResult.filename }}

或者在控制器中:

$this->getParameter('app_ul_avatar').$dbResult->getFilename();