首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gaufrette (带AWS) & Symfony 4-读一幅图

Gaufrette (带AWS) & Symfony 4-读一幅图
EN

Stack Overflow用户
提问于 2020-03-26 14:08:36
回答 1查看 759关注 0票数 1

下午好,

我试图显示来自AWS S3存储的图像。我使用了gaufrette文件配置,当我在AWS S3存储中上传文件时,它可以工作。

计量器配置:

代码语言:javascript
复制
knp_gaufrette:
    adapters:
        images:
            aws_s3:
                service_id: "infra.aws_s3.client"
                bucket_name: "%amazon_s3.bucket_name%"
                detect_content_type: true
                options:
                    directory: "%amazon_s3.directories.images%"
                    acl: public-read
        documents:
            aws_s3:
                service_id: "infra.aws_s3.client"
                bucket_name: "%amazon_s3.bucket_name%"
                detect_content_type: true
                options:
                    directory: "%amazon_s3.directories.documents%"
                    acl: public-read
        imports:
            aws_s3:
                service_id: "infra.aws_s3.client"
                bucket_name: "%amazon_s3.bucket_name%"
                detect_content_type: true
                options:
                    directory: "%amazon_s3.directories.imports%"
                    acl: public-read
    filesystems:
        images:
            adapter: images
            alias: images_filesystem
        documents:
            adapter: documents
            alias: documents_filesystem
        imports:
            adapter: imports
            alias: imports_filesystem

控制器代码:

代码语言:javascript
复制
<?php

namespace App\Application\Controller;

use App\Application\Controller\Rest\RestController;
use App\Domain\Entity\BuildingMedia;
use App\Domain\Entity\PropertyPicture;
use App\Infrastructure\Command\Command\CommandBus;
use App\Infrastructure\Repository\BuildingMediaRepository;
use App\Infrastructure\Repository\PropertyPictureRepository;
use Gaufrette\Filesystem;
use Gaufrette\StreamWrapper;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Swagger\Annotations as SWG;
use Nelmio\ApiDocBundle\Annotation\Operation;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;

class MediaController extends RestController
{
    /**
     * @var PropertyPictureRepository
     */
    private $propertyPictureRepository;

    /**
     * @var BuildingMediaRepository
     */
    private $buildingMediaRepository;

    /**
     * @var Filesystem
     */
    private $awsS3;

    /**
     * MediaController constructor.
     *
     * @param PropertyPictureRepository $propertyPictureRepository
     * @param BuildingMediaRepository   $buildingMediaRepository
     * @param Filesystem                $awsS3
     * @param SerializerInterface       $serializer
     * @param CommandBus                $commandBus
     */
    public function __construct(
        PropertyPictureRepository $propertyPictureRepository,
        BuildingMediaRepository $buildingMediaRepository,
        Filesystem $awsS3,
        SerializerInterface $serializer,
        CommandBus $commandBus
    ) {
        $this->propertyPictureRepository = $propertyPictureRepository;
        $this->buildingMediaRepository = $buildingMediaRepository;
        $this->awsS3 = $awsS3;

        parent::__construct($serializer, $commandBus);
    }

    /**
     * @Operation(
     *     tags={"Media"},
     *     summary="Read a property's picture.",
     *     @SWG\Response(
     *         response="200",
     *         description="OK"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="Bad request"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="Unauthorized"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="Access denied"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="Entity not found"
     *     ),
     *     @SWG\Response(
     *         response="500",
     *         description="Internal server error"
     *     )
     * )
     *
     * @ParamConverter("propertyPicture", converter="property_picture")
     *
     * @param PropertyPicture $propertyPicture
     *
     * @return BinaryFileResponse
     */
    public function propertyPictureReadAction(PropertyPicture $propertyPicture): BinaryFileResponse
    {
        $adapter = $this->awsS3->getAdapter();

        $filePath = $adapter->read(
            'group'.DIRECTORY_SEPARATOR.
            $this->getUser()->getGroupId().DIRECTORY_SEPARATOR.
            'property'.DIRECTORY_SEPARATOR.
            $propertyPicture->getProperty()->getIdValue().DIRECTORY_SEPARATOR.
            $propertyPicture->getFilename()
        );

        $response = new BinaryFileResponse($filepath);
        $response->headers->set('Content-Type', 'image/jpeg');
        $response->setContentDisposition(
            ResponseHeaderBag::DISPOSITION_INLINE,
            $propertyPicture->getFilename()
        );

        return $response;
    }
}

如果我尝试使用getLink() from $propertyPicture (该方法返回保存在数据库中的文件URL ),BinaryFileResponse就不会从给定的$propertyPicture中找到该文件。

我需要有来自Gaufrette的文件URL来在API响应中显示该文件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-27 11:11:57

在尝试了许多可能的解决方案之后,我已经找到了一个用于图片的解决方案(而且它工作得很好,即使在AWS S3中使用私有桶也是如此):

代码语言:javascript
复制
<?php

namespace App\Application\Controller;

use App\Application\Controller\Rest\RestController;
use App\Domain\Entity\BuildingMedia;
use App\Domain\Entity\PropertyPicture;
use App\Infrastructure\Command\Command\CommandBus;
use App\Infrastructure\Repository\BuildingMediaRepository;
use App\Infrastructure\Repository\PropertyPictureRepository;
use Gaufrette\Filesystem;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Response;
use Swagger\Annotations as SWG;
use Nelmio\ApiDocBundle\Annotation\Operation;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpKernel\Exception\HttpException;

class MediaController extends RestController
{
    /**
     * @var PropertyPictureRepository
     */
    private $propertyPictureRepository;

    /**
     * @var BuildingMediaRepository
     */
    private $buildingMediaRepository;

    /**
     * @var Filesystem
     */
    private $awsS3;

    /**
     * MediaController constructor.
     *
     * @param PropertyPictureRepository $propertyPictureRepository
     * @param BuildingMediaRepository   $buildingMediaRepository
     * @param Filesystem                $awsS3
     * @param SerializerInterface       $serializer
     * @param CommandBus                $commandBus
     */
    public function __construct(
        PropertyPictureRepository $propertyPictureRepository,
        BuildingMediaRepository $buildingMediaRepository,
        Filesystem $awsS3,
        SerializerInterface $serializer,
        CommandBus $commandBus
    ) {
        $this->propertyPictureRepository = $propertyPictureRepository;
        $this->buildingMediaRepository = $buildingMediaRepository;
        $this->awsS3 = $awsS3;

        parent::__construct($serializer, $commandBus);
    }

    /**
     * @Operation(
     *     tags={"Media"},
     *     summary="Read a property's picture.",
     *     @SWG\Response(
     *         response="200",
     *         description="OK"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="Bad request"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="Unauthorized"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="Access denied"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="Entity not found"
     *     ),
     *     @SWG\Response(
     *         response="500",
     *         description="Internal server error"
     *     )
     * )
     *
     * @ParamConverter("propertyPicture", converter="property_picture")
     *
     * @param PropertyPicture $propertyPicture
     *
     * @return Response
     */
    public function propertyPictureReadAction(PropertyPicture $propertyPicture): Response
    {
        $adapter = $this->awsS3->getAdapter();

        $content = $adapter->read(
            'group'.DIRECTORY_SEPARATOR.
            $this->getUser()->getGroupId().DIRECTORY_SEPARATOR.
            'property'.DIRECTORY_SEPARATOR.
            $propertyPicture->getProperty()->getIdValue().DIRECTORY_SEPARATOR.
            $propertyPicture->getFilename()
        );

        return new Response($content, 200, array(
                'Content-Type' => 'image/jpeg'
        ));
    }
}

read()方法从Gaufrette返回文件内容,而不是真正的路径。因此,我只需将返回值从BinaryFileResponse更改为Response,并手动设置Content-Type

下一次升级,如果您有相同的处理,是在保存文件时在数据库中设置MIME类型,并在需要使用API中类似的路由显示它时返回它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60869160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档