Gaufrette(使用 AWS)和 Symfony 4 - 阅读图片
Gaufrette (with AWS) & Symfony 4 - Read a picture
下午好,
我尝试显示来自 AWS S3 存储的图像。当我在 AWS S3 存储中上传文件时,我使用 gaufrette 文件配置。
Gaufrette 配置:
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
控制器代码:
<?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;
}
}
如果我尝试使用 $propertyPicture
中的 getLink()
(方法 returns 文件 URL 保存在数据库中),BinaryFileResponse
找不到文件来自给定 URL.
我需要从 Gaufrette 获得文件 URL 才能在 API 响应中显示该文件。
在尝试了许多可能的解决方案后,我找到了这个用于图片的解决方案(即使您在 AWS S3 中使用私有存储桶,它也能正常工作):
<?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
returns文件内容,而不是真实路径。所以,我刚刚将 returns 值从 BinaryFileResponse
更改为 Response
并手动设置了 Content-Type
.
下一次升级,如果你有相同的处理是在保存文件时在数据库中设置 MIME 类型,returns 当你需要像从你的 API.
下午好,
我尝试显示来自 AWS S3 存储的图像。当我在 AWS S3 存储中上传文件时,我使用 gaufrette 文件配置。
Gaufrette 配置:
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
控制器代码:
<?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;
}
}
如果我尝试使用 $propertyPicture
中的 getLink()
(方法 returns 文件 URL 保存在数据库中),BinaryFileResponse
找不到文件来自给定 URL.
我需要从 Gaufrette 获得文件 URL 才能在 API 响应中显示该文件。
在尝试了许多可能的解决方案后,我找到了这个用于图片的解决方案(即使您在 AWS S3 中使用私有存储桶,它也能正常工作):
<?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
returns文件内容,而不是真实路径。所以,我刚刚将 returns 值从 BinaryFileResponse
更改为 Response
并手动设置了 Content-Type
.
下一次升级,如果你有相同的处理是在保存文件时在数据库中设置 MIME 类型,returns 当你需要像从你的 API.