在Symfony 3中从文件夹中删除文件

8
我有一个控制器,其中包含一个createActioneditActiondeleteAction
我可以向数据库添加图片并从中删除它们。
当我遵循Symfony文档创建上传文件时,我也在我的config.yml中创建了这个路由。
parameters:
   uploaded_restaurants: "%kernel.root_dir%/../web/uploads/restaurants"

这是我上传文件的路由。
我的问题是,当我使用删除操作将图片从数据库中删除时,它可以正常完成。但是在 /web/uploads/restaurants 文件夹中并没有删除它们。 我试图找到一种方法能够同时在文件夹中删除它们,但是没有成功。
我也尝试使用 Filesystem() 来删除它们,但我可能写错了代码。
这是我的控制器:
    class MediaController extends Controller
{
    /**
     * @param Request $request
     * @param Restaurant $restaurant
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function newAction(Request $request, Restaurant $restaurant)
    {
        $media = new Media();
        $form = $this->createForm(MediaType\CreateType::class, $media);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $mediaList = $this->getDoctrine()->getRepository('AppBundle:Media')->findImageByRestaurantType($restaurant, $form->get('context')->getData());

            if ($mediaList == null || count($mediaList) < 1) {
                $media->setType('img')
                    ->setContext($form->get('context')->getData())
                    ;
            } else {
                $media = $mediaList;
            }

            $imageFile = $request->files->get('create')['name'];
            $targetDir = $this->getParameter('uploaded_restaurants');
            $imageName = $this->get('app.uploader')->upload($imageFile, $targetDir);

            /** @var  $originalName */
            $originalName = $imageFile->getClientOriginalName();
            $media->setName($imageName)
                ->setOriginalName($originalName)
                ->setCreatedAt(new \DateTime());

            $em = $this->getDoctrine()->getManager();
            $media->setRestaurant($restaurant);
            $em->persist($media);
            $em->flush();

            return $this->redirectToRoute('admin_restaurant_show_fr', array('id' => $restaurant->getId()));
        }
        return $this->render('admin/restaurant/media/new.html.twig', array(
            'restaurant' => $restaurant,
            'form' => $form->createView()
        ));
    }

    /**
     * @param Request $request
     * @param Media $media
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function editAction(Request $request, Media $media)
    {
        $em = $this->getDoctrine()->getManager();

        $editForm = $this->createForm(MediaType\EditType::class, $media);
        $editForm->handleRequest($request);
        $restaurant = $media->getRestaurant();

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $imageFile = $request->files->get('edit')['name'];
            $targetDir = $this->getParameter('uploaded_restaurants');
            $imageName = $this->get('app.uploader')->upload($imageFile, $targetDir);

            if ($request->files->get('edit')['name'] != null) {

                $fs = new Filesystem();
                try {
                    $fs->remove($this->get('kernel')->getRootDir() . '/../web/uploads/restaurants' . $media->getName());
                } catch (IOException $e) {
                    echo "error";
                }

                /** @var $originalName */
                $originalName = $imageFile->getClientOriginalName();
                $media->setName($imageName)
                    ->setOriginalName($originalName)
                    ->setUpdatedAt(new \DateTime());
            }
            $em->persist($media);
            $em->flush();

            return $this->redirectToRoute('admin_restaurant_show_fr', array('id' => $restaurant->getId()));
        }
        return $this->render('admin/restaurant/media/edit.html.twig', array(
            'media' => $media,
            'restaurant' => $restaurant,
            'editForm' => $editForm->createView()
        ));
    }

    /**
     * @param Media $media
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function deleteAction(Media $media)
    {
        $restaurant = $media->getRestaurant();
        $em = $this->getDoctrine()->getManager();
        $em->remove($media);
        $em->flush();

        return $this->redirectToRoute('admin_restaurant_show_fr', array('id' => $restaurant->getId()));
    }
}

正如您在editAction中看到的,我试图添加一个Filesystem以便删除文件。

我的问题

我应该怎样在我的editActiondeleteAction中操作,以便从目录中正确删除我的文件? 如果您不是很理解我的代码,您能否给我展示一个有效的例子? 谢谢


你有没有考虑使用VichUploaderBundle(它甚至在官方文档中被建议)?它已经实现了这个功能。 - kero
嗨@kero,感谢您的评论。实际上,在我的项目中,我不能使用任何捆绑包,因为我的主管希望我这样做....就像那样 :/ 所以无论如何,谢谢您的答案,我将在未来的项目中考虑使用vich :) - chicken burger
2个回答

16

在编辑或删除媒体时,您可以使用其文件名来访问现有对象,例如:

public function deleteAction(Media $media){ ... }

Doctrine将从URL中读取id,并从数据库加载相应的媒体。您可以使用此对象获取旧图像位置,然后删除该图像。

// getName() will contain the complete filename with path.
// Check your showAction where you call `setName($imageName)`
$filename = $media->getName();

$filesystem = new Filesystem();
$filesystem->remove($filename);

你可以在editAction中使用与提供的代码相同的操作。


嗨 @dbrumann,谢谢你的回答。只需要你的两行代码就可以解决问题了?真的这么简单吗?我现在不能测试,因为我要离开办公室了,不过我会回家试试看。 - chicken burger
2
我使用了你的逻辑添加了这一行代码 $fs = new Filesystem(); $fs->remove($this->get('kernel')->getRootDir().'/../web/uploads/restaurants/'.$oldName); ,它起作用了 :) 谢谢你 - chicken burger

0

config/services.yaml

parameters:
      img_dir: "%kernel.project_dir%/public/img"
      public_dir: "%kernel.project_dir%/public"

控制器编辑

public function edit(Request $request, Layanan $layanan, EntityManagerInterface $entityManager): Response
{
// ....
    $file = $form->get('image')->getData();
    $fs = new Filesystem();
    if ($form->isSubmitted() && $form->isValid()) {
        if ($file) {
            $fname = $layanan->getImage();
            $fs->remove($this->getParameter('public_dir').'/img/'.$fname);
            $newFilename = $originalfilename . '-' . uniqid() . '.' . $file->guessExtension();
            try {
                $file->move(
                    $this->getParameter('img_dir'),
                    $newFilename
                );
            } catch (FileException $e) {
                // ... handle exception if something happens during file upload
            }
            $layanan->setImage($newFilename);
        }
//...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接