将任何 base64 文件转换为文件并移动到 php / Symfony 4 中的目标路径
Converting any base64 file to a file and moving to the targeted path in php / Symfony 4
提前致谢 我正在 symfony 4
中创建 API 只是为了上传 base64 image
或通过 POSTMAN
的任何文件,我必须将文件移动到目标目录。我在控制器中编写了以下代码。通过控制器我试图将文件移动到目录,但是
我得到的错误是:
Uncaught Warning: file_put_contents(images/5c78de505abdd.svg): failed to open stream: No such file or directory {"exception":"[object] (ErrorException(code: 0): Warning: file_put_contents(images/5c78de505abdd.svg): failed to open stream: No such file or directory at /home/ragiththomas/Sites/asco-forum/src/Modules/Forum/ForumController.php:1107)"} []
POSTMAN 请求 svg 文件:
{"postFile":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0naXNvLTg4NTktMSc/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICdodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQnPgo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjAzLjU0MyAyMDMuNTQzIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjAzLjU0MyAyMDMuNTQzIj4KICA8Zz4KICAgIDxwYXRoIGZpbGw9IiMwMDQ1N2MiIGQ9Im0xOTQuMTM5LDExLjkxOGgtMzkuMzE1di01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtMzUuMDUzdi01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtMzMuNTYzdi01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtNDAuODA0Yy0zLjMxMywwLTYsMi42ODctNiw2djEzNS41NzJjMCwzLjMxMyAyLjY4Nyw2IDYsNmgzNi44MjZjNS45MDEsMjUuMjE0IDI4LjU1NSw0NC4wNTMgNTUuNTQxLDQ0LjA1M3M0OS42NC0xOC44NCA1NS41NDEtNDQuMDUzaDM2LjgyNmMzLjMxMywwIDYtMi42ODcgNi02di0xMzUuNTcyYzAuMDAxLTMuMzEzLTIuNjg1LTYtNS45OTktNnptLTE0My45MzEsMTJ2NS40MjJjMCwzLjMxMyAyLjY4Nyw2IDYsNnM2LTIuNjg3IDYtNnYtNS40MjJoMzMuNTYzdjUuNDIyYzAsMy4zMTMgMi42ODcsNiA2LDZzNi0yLjY4NyA2LTZ2LTUuNDIyaDM1LjA1M3Y1LjQyMmMwLDMuMzEzIDIuNjg3LDYgNiw2czYtMi42ODcgNi02di01LjQyMmgzMy4zMTV2MjQuNTM2aC0xNzIuNzM1di0yNC41MzZoMzQuODA0em01MS41NjMsMTY3LjYyNWMtMjQuODQyLDAtNDUuMDUzLTIwLjIxMS00NS4wNTMtNDUuMDUzczIwLjIxMS00NS4wNTMgNDUuMDUzLTQ1LjA1MyA0NS4wNTMsMjAuMjEgNDUuMDUzLDQ1LjA1My0yMC4yMSw0NS4wNTMtNDUuMDUzLDQ1LjA1M3ptNTcuMDI4LTQ0LjA1M2MwLjAwNi0wLjMzNCAwLjAyNS0wLjY2NSAwLjAyNS0xIDAtMzEuNDU5LTI1LjU5NC01Ny4wNTMtNTcuMDUzLTU3LjA1M3MtNTcuMDUzLDI1LjU5NC01Ny4wNTMsNTcuMDUzYzAsMC4zMzUgMC4wMiwwLjY2NiAwLjAyNSwxaC0yOS4zNHYtODcuMDM1aDE3Mi43MzV2ODcuMDM1aC0yOS4zMzl6Ii8+CiAgICA8cGF0aCBmaWxsPSIjMDA0NTdjIiBkPSJtMTA3Ljc3MSwxNDguMDA0di0yOS4wMjZjMC0zLjMxMy0yLjY4Ny02LTYtNnMtNiwyLjY4Ny02LDZ2MzEuNTEyYzAsMS41OTEgMC42MzIsMy4xMTcgMS43NTcsNC4yNDNsMTMuNzksMTMuNzkxYzEuMTcyLDEuMTcxIDIuNzA3LDEuNzU3IDQuMjQzLDEuNzU3IDEuNTM1LDAgMy4wNzEtMC41ODYgNC4yNDMtMS43NTcgMi4zNDMtMi4zNDMgMi4zNDMtNi4xNDIgMC04LjQ4NWwtMTIuMDMzLTEyLjAzNXoiLz4KICA8L2c+Cjwvc3ZnPgo="}
控制器文件:
/**
* @route("/uploadForumFiles", name="upload_forum_files", methods="POST")
*
* @access public
*
* @return JsonResponse
*/
public function uploadForumFiles(Request $request, PostsInterceptor $apiInterceptor, ContainerInterface $container): JsonResponse {
try {
$fileContent = $requestDtoObj->postFile;
$target_dir = 'images/'; // add the specific path to save the file
$decoded_file = base64_decode($fileContent); // decode the file
$mime_type = finfo_buffer(finfo_open(), $decoded_file, FILEINFO_MIME_TYPE); // extract mime type
$extension = $this->mime2ext($mime_type); // extract extension from mime type
$file = uniqid() .'.'. $extension; // rename file as a unique name
$file_dir = $target_dir. uniqid().'.'.$extension;
file_put_contents($target_dir, $file);
echo $file_dir; die;
} catch (Exception $ex) {
$this->logger->writeLog("ERROR", "Exception while uploading a file " . $ex->getMessage() . 'at line - ' . $ex->getLine() . ' in file' . $ex->getFile());
return $this->responseHandler->getFailedResponse(array($ex->getMessage()), $apiInterceptor);
}
}
public function mime2ext($mime){
$all_mimes = '{"png":["image/png","image/x-png"],"bmp":["image/bmp","image/x-bmp",
"image/x-bitmap","image/x-xbitmap","image/x-win-bitmap","image/x-windows-bmp",
"image/ms-bmp","image/x-ms-bmp","application/bmp","application/x-bmp",
"application/x-win-bitmap"],"gif":["image/gif"],"jpeg":["image/jpeg",
"image/pjpeg"],"xspf":["application/xspf+xml"],"vlc":["application/videolan"],
"wmv":["video/x-ms-wmv","video/x-ms-asf"],"au":["audio/x-au"],
"ac3":["audio/ac3"],"flac":["audio/x-flac"],"ogg":["audio/ogg",
"video/ogg","application/ogg"],"kmz":["application/vnd.google-earth.kmz"],
"kml":["application/vnd.google-earth.kml+xml"],"rtx":["text/richtext"],
"rtf":["text/rtf"],"jar":["application/java-archive","application/x-java-application",
"application/x-jar"],"zip":["application/x-zip","application/zip",
"application/x-zip-compressed","application/s-compressed","multipart/x-zip"],
"7zip":["application/x-compressed"],"xml":["application/xml","text/xml"],
"svg":["image/svg+xml","application/octet-stream"],"3g2":["video/3gpp2"],"3gp":["video/3gp","video/3gpp"],
"mp4":["video/mp4"],"m4a":["audio/x-m4a"],"f4v":["video/x-f4v"],"flv":["video/x-flv"],
"webm":["video/webm"],"aac":["audio/x-acc"],"m4u":["application/vnd.mpegurl"],
"pdf":["application/pdf"],
"pptx":["application/vnd.openxmlformats-officedocument.presentationml.presentation"],
"ppt":["application/powerpoint","application/vnd.ms-powerpoint","application/vnd.ms-office",
"application/msword"],"docx":["application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
"xlsx":["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],
"xl":["application/excel"],"xls":["application/msexcel","application/x-msexcel","application/x-ms-excel",
"application/x-excel","application/x-dos_ms_excel","application/xls","application/x-xls"],
"xsl":["text/xsl"],"mpeg":["video/mpeg"],"mov":["video/quicktime"],"avi":["video/x-msvideo",
"video/msvideo","video/avi","application/x-troff-msvideo"],"movie":["video/x-sgi-movie"],
"log":["text/x-log"],"txt":["text/plain"],"css":["text/css"],"html":["text/html"],
"wav":["audio/x-wav","audio/wave","audio/wav"],"xhtml":["application/xhtml+xml"],
"tar":["application/x-tar"],"tgz":["application/x-gzip-compressed"],"psd":["application/x-photoshop",
"image/vnd.adobe.photoshop"],"exe":["application/x-msdownload"],"js":["application/x-javascript"],
"mp3":["audio/mpeg","audio/mpg","audio/mpeg3","audio/mp3"],"rar":["application/x-rar","application/rar",
"application/x-rar-compressed"],"gzip":["application/x-gzip"],"hqx":["application/mac-binhex40",
"application/mac-binhex","application/x-binhex40","application/x-mac-binhex40"],
"cpt":["application/mac-compactpro"],"bin":["application/macbinary","application/mac-binary",
"application/x-binary","application/x-macbinary"],"oda":["application/oda"],
"ai":["application/postscript"],"smil":["application/smil"],"mif":["application/vnd.mif"],
"wbxml":["application/wbxml"],"wmlc":["application/wmlc"],"dcr":["application/x-director"],
"dvi":["application/x-dvi"],"gtar":["application/x-gtar"],"php":["application/x-httpd-php",
"application/php","application/x-php","text/php","text/x-php","application/x-httpd-php-source"],
"swf":["application/x-shockwave-flash"],"sit":["application/x-stuffit"],"z":["application/x-compress"],
"mid":["audio/midi"],"aif":["audio/x-aiff","audio/aiff"],"ram":["audio/x-pn-realaudio"],
"rpm":["audio/x-pn-realaudio-plugin"],"ra":["audio/x-realaudio"],"rv":["video/vnd.rn-realvideo"],
"jp2":["image/jp2","video/mj2","image/jpx","image/jpm"],"tiff":["image/tiff"],
"eml":["message/rfc822"],"pem":["application/x-x509-user-cert","application/x-pem-file"],
"p10":["application/x-pkcs10","application/pkcs10"],"p12":["application/x-pkcs12"],
"p7a":["application/x-pkcs7-signature"],"p7c":["application/pkcs7-mime","application/x-pkcs7-mime"],"p7r":["application/x-pkcs7-certreqresp"],"p7s":["application/pkcs7-signature"],"crt":["application/x-x509-ca-cert","application/pkix-cert"],"crl":["application/pkix-crl","application/pkcs-crl"],"pgp":["application/pgp"],"gpg":["application/gpg-keys"],"rsa":["application/x-pkcs7"],"ics":["text/calendar"],"zsh":["text/x-scriptzsh"],"cdr":["application/cdr","application/coreldraw","application/x-cdr","application/x-coreldraw","image/cdr","image/x-cdr","zz-application/zz-winassoc-cdr"],"wma":["audio/x-ms-wma"],"vcf":["text/x-vcard"],"srt":["text/srt"],"vtt":["text/vtt"],"ico":["image/x-icon","image/x-ico","image/vnd.microsoft.icon"],"csv":["text/x-comma-separated-values","text/comma-separated-values","application/vnd.msexcel"],"json":["application/json","text/json"]}';
$all_mimes = json_decode($all_mimes,true);
foreach ($all_mimes as $key => $value) {
if(array_search($mime,$value) !== false) return $key;
}
return false;
}
如果文件不存在,file_put_contents
会创建该文件,但如果您尝试将该文件放在不存在的目录中,则会失败。所以你应该尝试以下方法:
- 检查
images
目录是否存在
- 检查目录的写入权限
- 尝试使用绝对路径,所以在您的情况下可能
$target_dir = '/home/ragiththomas/Sites/asco-forum/images/';
使用symfony4,另一种方法是使用vichuploadbundle。我们可以用图片来举例。
- 根据这个文档integrating vichuploadbundle,安装vichupload并配置
composer require vich/uploader-bundle
在 config/bundles.php 文件中不要忘记检查此行是否出现:
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
在config/services.yaml中,添加这个配置(只是一个例子)
# config/services.yaml
parameters:
app.path.images: /uploads/images
不要忘记在 public 目录中创建上传目录,在上传目录中创建图像目录。
然后你配置文件 config/packages/vich_uploader.yaml 如下:
# config/packages/vich_uploader.yaml
vich_uploader:
db_driver: orm
mappings:
object_image:
uri_prefix: '%app.path.images%'
upload_destination: '%kernel.project_dir%/public%app.path.images%'
namer: Vich\UploaderBundle\Naming\UniqidNamer
delete_on_remove: true
delete_on_update: true
- 创建图像实体(带有验证断言),如:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* @Vich\Uploadable()
* @ORM\Table(name="image")
*/
class Image
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var File|null
* @Assert\NotBlank(message="Please upload a file.")
* @Assert\File(
* maxSize = "1M",
* maxSizeMessage = "Maximum size allowed : {{ limit }} {{ suffix }}.",
* mimeTypes = {"image/png", "image/jpg", "image/jpeg"},
* mimeTypesMessage = "Allowed formats : png, jpg, jpeg."
* )
* @Vich\UploadableField(mapping="object_image", fileNameProperty="imageName")
*/
private $imageFile;
/**
* @var string|null
*
* @ORM\Column(type="string", length=255)
*/
private $imageName;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*
*/
private $createdAt;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*/
private $updatedAt;
public function __construct()
{
$this->createdAt = new \DateTime('now');
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return \DateTime
*/
public function getCreatedAt(): \DateTime
{
return $this->createdAt;
}
/**
* @param \DateTime $createdAt
* @return Image
*/
public function setCreatedAt(\DateTime $createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return \DateTime
*/
public function getUpdatedAt(): \DateTime
{
return $this->updatedAt;
}
/**
* @param \DateTime $updatedAt
* @return Image
*/
public function setUpdatedAt(\DateTime $updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return null|File
*/
public function getImageFile(): ?File
{
return $this->imageFile;
}
/**
* @param null|File $imageFile
* @return Image
*/
public function setImageFile(?File $imageFile): Image
{
$this->imageFile = $imageFile;
if($this->imageFile instanceof UploadedFile) {
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return null|string
*/
public function getImageName(): ?string
{
return $this->imageName;
}
/**
* @param null|string $imageName
* @return Image
*/
public function setImageName(?string $imageName): Image
{
$this->imageName = $imageName;
return $this;
}
}
创建一个表单图像实体,如:
<?php
namespace App\Form;
use App\Entity\Image;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', FileType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Image::class
]);
}
}
- 您创建一个 UploadedBase64File 服务(在您将创建的 Utils 目录中),如
<?php
namespace App\Utils;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class UploadedBase64File extends UploadedFile
{
public function __construct(string $base64Content, string $originalName)
{
$filePath = tempnam(sys_get_temp_dir(), 'UploadedFile');
$data = base64_decode($this->getBase64String($base64Content));
file_put_contents($filePath, $data);
$error = null;
$mimeType = null;
$test = true;
parent::__construct($filePath, $originalName, $mimeType, $error, $test);
}
private function getBase64String(string $base64Content)
{
$data = explode(';base64,', $base64Content);
return $data[1];
}
}
- 最后在控制器中,你可以做类似的事情:
<?php
namespace App\Controller\Api;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use App\Utils\UploadedBase64File;
class CoreController extends AbstractController
{
/**
* @Route("/api/images", methods={"POST"}, name="api_add_image")
*/
public function addImage(Request $request)
{
$data = json_decode($request->getContent(), true);
if($data === null
|| !is_array($data)
|| count($data) !== 1
|| !isset($data['image']['name'], $data['image']['value'])
|| count($data['image']) !== 2
) {
// Throw invalid format request for image
}
$imageFile = new UploadedBase64File($data['image']['value'], $data['image']['name']);
$image = new Image();
$form = $this->createForm(ImageType::class, $image, ['csrf_protection' => false]);
$form->submit(['imageFile' => $imageFile]);
if(!($form->isSubmitted() && $form->isValid())) {
// Send json form error
}
// Persist, do thing you want to do and send json response
}
}
如果你想在邮递员中进行测试,你可以这样做:
{
"image": {
"name": "originalfilename.png",
"value": "base64 content"
}
}
这是其他解决方案的尝试。
提前致谢 我正在 symfony 4
中创建 API 只是为了上传 base64 image
或通过 POSTMAN
的任何文件,我必须将文件移动到目标目录。我在控制器中编写了以下代码。通过控制器我试图将文件移动到目录,但是
我得到的错误是:
Uncaught Warning: file_put_contents(images/5c78de505abdd.svg): failed to open stream: No such file or directory {"exception":"[object] (ErrorException(code: 0): Warning: file_put_contents(images/5c78de505abdd.svg): failed to open stream: No such file or directory at /home/ragiththomas/Sites/asco-forum/src/Modules/Forum/ForumController.php:1107)"} []
POSTMAN 请求 svg 文件:
{"postFile":"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0naXNvLTg4NTktMSc/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICdodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQnPgo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjAzLjU0MyAyMDMuNTQzIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjAzLjU0MyAyMDMuNTQzIj4KICA8Zz4KICAgIDxwYXRoIGZpbGw9IiMwMDQ1N2MiIGQ9Im0xOTQuMTM5LDExLjkxOGgtMzkuMzE1di01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtMzUuMDUzdi01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtMzMuNTYzdi01LjkxOGMwLTMuMzEzLTIuNjg3LTYtNi02cy02LDIuNjg3LTYsNnY1LjkxOGgtNDAuODA0Yy0zLjMxMywwLTYsMi42ODctNiw2djEzNS41NzJjMCwzLjMxMyAyLjY4Nyw2IDYsNmgzNi44MjZjNS45MDEsMjUuMjE0IDI4LjU1NSw0NC4wNTMgNTUuNTQxLDQ0LjA1M3M0OS42NC0xOC44NCA1NS41NDEtNDQuMDUzaDM2LjgyNmMzLjMxMywwIDYtMi42ODcgNi02di0xMzUuNTcyYzAuMDAxLTMuMzEzLTIuNjg1LTYtNS45OTktNnptLTE0My45MzEsMTJ2NS40MjJjMCwzLjMxMyAyLjY4Nyw2IDYsNnM2LTIuNjg3IDYtNnYtNS40MjJoMzMuNTYzdjUuNDIyYzAsMy4zMTMgMi42ODcsNiA2LDZzNi0yLjY4NyA2LTZ2LTUuNDIyaDM1LjA1M3Y1LjQyMmMwLDMuMzEzIDIuNjg3LDYgNiw2czYtMi42ODcgNi02di01LjQyMmgzMy4zMTV2MjQuNTM2aC0xNzIuNzM1di0yNC41MzZoMzQuODA0em01MS41NjMsMTY3LjYyNWMtMjQuODQyLDAtNDUuMDUzLTIwLjIxMS00NS4wNTMtNDUuMDUzczIwLjIxMS00NS4wNTMgNDUuMDUzLTQ1LjA1MyA0NS4wNTMsMjAuMjEgNDUuMDUzLDQ1LjA1My0yMC4yMSw0NS4wNTMtNDUuMDUzLDQ1LjA1M3ptNTcuMDI4LTQ0LjA1M2MwLjAwNi0wLjMzNCAwLjAyNS0wLjY2NSAwLjAyNS0xIDAtMzEuNDU5LTI1LjU5NC01Ny4wNTMtNTcuMDUzLTU3LjA1M3MtNTcuMDUzLDI1LjU5NC01Ny4wNTMsNTcuMDUzYzAsMC4zMzUgMC4wMiwwLjY2NiAwLjAyNSwxaC0yOS4zNHYtODcuMDM1aDE3Mi43MzV2ODcuMDM1aC0yOS4zMzl6Ii8+CiAgICA8cGF0aCBmaWxsPSIjMDA0NTdjIiBkPSJtMTA3Ljc3MSwxNDguMDA0di0yOS4wMjZjMC0zLjMxMy0yLjY4Ny02LTYtNnMtNiwyLjY4Ny02LDZ2MzEuNTEyYzAsMS41OTEgMC42MzIsMy4xMTcgMS43NTcsNC4yNDNsMTMuNzksMTMuNzkxYzEuMTcyLDEuMTcxIDIuNzA3LDEuNzU3IDQuMjQzLDEuNzU3IDEuNTM1LDAgMy4wNzEtMC41ODYgNC4yNDMtMS43NTcgMi4zNDMtMi4zNDMgMi4zNDMtNi4xNDIgMC04LjQ4NWwtMTIuMDMzLTEyLjAzNXoiLz4KICA8L2c+Cjwvc3ZnPgo="}
控制器文件:
/**
* @route("/uploadForumFiles", name="upload_forum_files", methods="POST")
*
* @access public
*
* @return JsonResponse
*/
public function uploadForumFiles(Request $request, PostsInterceptor $apiInterceptor, ContainerInterface $container): JsonResponse {
try {
$fileContent = $requestDtoObj->postFile;
$target_dir = 'images/'; // add the specific path to save the file
$decoded_file = base64_decode($fileContent); // decode the file
$mime_type = finfo_buffer(finfo_open(), $decoded_file, FILEINFO_MIME_TYPE); // extract mime type
$extension = $this->mime2ext($mime_type); // extract extension from mime type
$file = uniqid() .'.'. $extension; // rename file as a unique name
$file_dir = $target_dir. uniqid().'.'.$extension;
file_put_contents($target_dir, $file);
echo $file_dir; die;
} catch (Exception $ex) {
$this->logger->writeLog("ERROR", "Exception while uploading a file " . $ex->getMessage() . 'at line - ' . $ex->getLine() . ' in file' . $ex->getFile());
return $this->responseHandler->getFailedResponse(array($ex->getMessage()), $apiInterceptor);
}
}
public function mime2ext($mime){
$all_mimes = '{"png":["image/png","image/x-png"],"bmp":["image/bmp","image/x-bmp",
"image/x-bitmap","image/x-xbitmap","image/x-win-bitmap","image/x-windows-bmp",
"image/ms-bmp","image/x-ms-bmp","application/bmp","application/x-bmp",
"application/x-win-bitmap"],"gif":["image/gif"],"jpeg":["image/jpeg",
"image/pjpeg"],"xspf":["application/xspf+xml"],"vlc":["application/videolan"],
"wmv":["video/x-ms-wmv","video/x-ms-asf"],"au":["audio/x-au"],
"ac3":["audio/ac3"],"flac":["audio/x-flac"],"ogg":["audio/ogg",
"video/ogg","application/ogg"],"kmz":["application/vnd.google-earth.kmz"],
"kml":["application/vnd.google-earth.kml+xml"],"rtx":["text/richtext"],
"rtf":["text/rtf"],"jar":["application/java-archive","application/x-java-application",
"application/x-jar"],"zip":["application/x-zip","application/zip",
"application/x-zip-compressed","application/s-compressed","multipart/x-zip"],
"7zip":["application/x-compressed"],"xml":["application/xml","text/xml"],
"svg":["image/svg+xml","application/octet-stream"],"3g2":["video/3gpp2"],"3gp":["video/3gp","video/3gpp"],
"mp4":["video/mp4"],"m4a":["audio/x-m4a"],"f4v":["video/x-f4v"],"flv":["video/x-flv"],
"webm":["video/webm"],"aac":["audio/x-acc"],"m4u":["application/vnd.mpegurl"],
"pdf":["application/pdf"],
"pptx":["application/vnd.openxmlformats-officedocument.presentationml.presentation"],
"ppt":["application/powerpoint","application/vnd.ms-powerpoint","application/vnd.ms-office",
"application/msword"],"docx":["application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
"xlsx":["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],
"xl":["application/excel"],"xls":["application/msexcel","application/x-msexcel","application/x-ms-excel",
"application/x-excel","application/x-dos_ms_excel","application/xls","application/x-xls"],
"xsl":["text/xsl"],"mpeg":["video/mpeg"],"mov":["video/quicktime"],"avi":["video/x-msvideo",
"video/msvideo","video/avi","application/x-troff-msvideo"],"movie":["video/x-sgi-movie"],
"log":["text/x-log"],"txt":["text/plain"],"css":["text/css"],"html":["text/html"],
"wav":["audio/x-wav","audio/wave","audio/wav"],"xhtml":["application/xhtml+xml"],
"tar":["application/x-tar"],"tgz":["application/x-gzip-compressed"],"psd":["application/x-photoshop",
"image/vnd.adobe.photoshop"],"exe":["application/x-msdownload"],"js":["application/x-javascript"],
"mp3":["audio/mpeg","audio/mpg","audio/mpeg3","audio/mp3"],"rar":["application/x-rar","application/rar",
"application/x-rar-compressed"],"gzip":["application/x-gzip"],"hqx":["application/mac-binhex40",
"application/mac-binhex","application/x-binhex40","application/x-mac-binhex40"],
"cpt":["application/mac-compactpro"],"bin":["application/macbinary","application/mac-binary",
"application/x-binary","application/x-macbinary"],"oda":["application/oda"],
"ai":["application/postscript"],"smil":["application/smil"],"mif":["application/vnd.mif"],
"wbxml":["application/wbxml"],"wmlc":["application/wmlc"],"dcr":["application/x-director"],
"dvi":["application/x-dvi"],"gtar":["application/x-gtar"],"php":["application/x-httpd-php",
"application/php","application/x-php","text/php","text/x-php","application/x-httpd-php-source"],
"swf":["application/x-shockwave-flash"],"sit":["application/x-stuffit"],"z":["application/x-compress"],
"mid":["audio/midi"],"aif":["audio/x-aiff","audio/aiff"],"ram":["audio/x-pn-realaudio"],
"rpm":["audio/x-pn-realaudio-plugin"],"ra":["audio/x-realaudio"],"rv":["video/vnd.rn-realvideo"],
"jp2":["image/jp2","video/mj2","image/jpx","image/jpm"],"tiff":["image/tiff"],
"eml":["message/rfc822"],"pem":["application/x-x509-user-cert","application/x-pem-file"],
"p10":["application/x-pkcs10","application/pkcs10"],"p12":["application/x-pkcs12"],
"p7a":["application/x-pkcs7-signature"],"p7c":["application/pkcs7-mime","application/x-pkcs7-mime"],"p7r":["application/x-pkcs7-certreqresp"],"p7s":["application/pkcs7-signature"],"crt":["application/x-x509-ca-cert","application/pkix-cert"],"crl":["application/pkix-crl","application/pkcs-crl"],"pgp":["application/pgp"],"gpg":["application/gpg-keys"],"rsa":["application/x-pkcs7"],"ics":["text/calendar"],"zsh":["text/x-scriptzsh"],"cdr":["application/cdr","application/coreldraw","application/x-cdr","application/x-coreldraw","image/cdr","image/x-cdr","zz-application/zz-winassoc-cdr"],"wma":["audio/x-ms-wma"],"vcf":["text/x-vcard"],"srt":["text/srt"],"vtt":["text/vtt"],"ico":["image/x-icon","image/x-ico","image/vnd.microsoft.icon"],"csv":["text/x-comma-separated-values","text/comma-separated-values","application/vnd.msexcel"],"json":["application/json","text/json"]}';
$all_mimes = json_decode($all_mimes,true);
foreach ($all_mimes as $key => $value) {
if(array_search($mime,$value) !== false) return $key;
}
return false;
}
file_put_contents
会创建该文件,但如果您尝试将该文件放在不存在的目录中,则会失败。所以你应该尝试以下方法:
- 检查
images
目录是否存在 - 检查目录的写入权限
- 尝试使用绝对路径,所以在您的情况下可能
$target_dir = '/home/ragiththomas/Sites/asco-forum/images/';
使用symfony4,另一种方法是使用vichuploadbundle。我们可以用图片来举例。
- 根据这个文档integrating vichuploadbundle,安装vichupload并配置
composer require vich/uploader-bundle
在 config/bundles.php 文件中不要忘记检查此行是否出现:
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
在config/services.yaml中,添加这个配置(只是一个例子)
# config/services.yaml
parameters:
app.path.images: /uploads/images
不要忘记在 public 目录中创建上传目录,在上传目录中创建图像目录。
然后你配置文件 config/packages/vich_uploader.yaml 如下:
# config/packages/vich_uploader.yaml
vich_uploader:
db_driver: orm
mappings:
object_image:
uri_prefix: '%app.path.images%'
upload_destination: '%kernel.project_dir%/public%app.path.images%'
namer: Vich\UploaderBundle\Naming\UniqidNamer
delete_on_remove: true
delete_on_update: true
- 创建图像实体(带有验证断言),如:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* @Vich\Uploadable()
* @ORM\Table(name="image")
*/
class Image
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var File|null
* @Assert\NotBlank(message="Please upload a file.")
* @Assert\File(
* maxSize = "1M",
* maxSizeMessage = "Maximum size allowed : {{ limit }} {{ suffix }}.",
* mimeTypes = {"image/png", "image/jpg", "image/jpeg"},
* mimeTypesMessage = "Allowed formats : png, jpg, jpeg."
* )
* @Vich\UploadableField(mapping="object_image", fileNameProperty="imageName")
*/
private $imageFile;
/**
* @var string|null
*
* @ORM\Column(type="string", length=255)
*/
private $imageName;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*
*/
private $createdAt;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*/
private $updatedAt;
public function __construct()
{
$this->createdAt = new \DateTime('now');
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return \DateTime
*/
public function getCreatedAt(): \DateTime
{
return $this->createdAt;
}
/**
* @param \DateTime $createdAt
* @return Image
*/
public function setCreatedAt(\DateTime $createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return \DateTime
*/
public function getUpdatedAt(): \DateTime
{
return $this->updatedAt;
}
/**
* @param \DateTime $updatedAt
* @return Image
*/
public function setUpdatedAt(\DateTime $updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return null|File
*/
public function getImageFile(): ?File
{
return $this->imageFile;
}
/**
* @param null|File $imageFile
* @return Image
*/
public function setImageFile(?File $imageFile): Image
{
$this->imageFile = $imageFile;
if($this->imageFile instanceof UploadedFile) {
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return null|string
*/
public function getImageName(): ?string
{
return $this->imageName;
}
/**
* @param null|string $imageName
* @return Image
*/
public function setImageName(?string $imageName): Image
{
$this->imageName = $imageName;
return $this;
}
}
创建一个表单图像实体,如:
<?php
namespace App\Form;
use App\Entity\Image;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', FileType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Image::class
]);
}
}
- 您创建一个 UploadedBase64File 服务(在您将创建的 Utils 目录中),如
<?php
namespace App\Utils;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class UploadedBase64File extends UploadedFile
{
public function __construct(string $base64Content, string $originalName)
{
$filePath = tempnam(sys_get_temp_dir(), 'UploadedFile');
$data = base64_decode($this->getBase64String($base64Content));
file_put_contents($filePath, $data);
$error = null;
$mimeType = null;
$test = true;
parent::__construct($filePath, $originalName, $mimeType, $error, $test);
}
private function getBase64String(string $base64Content)
{
$data = explode(';base64,', $base64Content);
return $data[1];
}
}
- 最后在控制器中,你可以做类似的事情:
<?php
namespace App\Controller\Api;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use App\Utils\UploadedBase64File;
class CoreController extends AbstractController
{
/**
* @Route("/api/images", methods={"POST"}, name="api_add_image")
*/
public function addImage(Request $request)
{
$data = json_decode($request->getContent(), true);
if($data === null
|| !is_array($data)
|| count($data) !== 1
|| !isset($data['image']['name'], $data['image']['value'])
|| count($data['image']) !== 2
) {
// Throw invalid format request for image
}
$imageFile = new UploadedBase64File($data['image']['value'], $data['image']['name']);
$image = new Image();
$form = $this->createForm(ImageType::class, $image, ['csrf_protection' => false]);
$form->submit(['imageFile' => $imageFile]);
if(!($form->isSubmitted() && $form->isValid())) {
// Send json form error
}
// Persist, do thing you want to do and send json response
}
}
如果你想在邮递员中进行测试,你可以这样做:
{
"image": {
"name": "originalfilename.png",
"value": "base64 content"
}
}
这是其他解决方案的尝试。