通过上传使用Symfony2的和放API的图像文件; FOSRESTBundle [英] Uploading image file through API using Symfony2 & FOSRESTBundle

查看:486
本文介绍了通过上传使用Symfony2的和放API的图像文件; FOSRESTBundle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在编码的API使用Symfony2中,FOSRESTBundle和Vichuploader文件上传Instagram的喜欢的照片共享应用程序。

I have been coding an API for a photo sharing app like Instagram using Symfony2, FOSRESTBundle, and Vichuploader for file uploads.

我能够解决GET和POST请求,但我无法找到如何连接到一个POST请求一个例子,实际的图像,这样,在我的情况下,可以Vichuploader抓住它,并帮助我文件上传

I'm able to work around GET and POST requests, but I can't find an example of how to attach to a POST request, the actual image so that in my case, Vichuploader can grab it and help me out with the file upload.

顺便说一句,我可以使用通过使用正常形态提到堆栈上传文件没有问题。

By the way, I can upload a file without issue using the stack mentioned through the use of a normal form.

感谢

狮子座

推荐答案

我一直在寻找一个关于完全相同的问题的解决方案。下面是我做的。

I have been looking for a solution about the exact same problem. Here is what I did.

首先让我解释一下我的约束。我希望我的API是充满JSON,并采取HTTP协议的功率(头,方法等)。我选择使用:

First let me explain my constraints. I wanted my API to be full JSON and to take power of the HTTP protocol (headers, methods, etc.). I chose to use:


  • 的Symfony2为一切几乎是为你做,只是code你的业务逻辑。

  • Doctrine2因为默认情况下与Symfony2中,并提供了一​​种方法通过改变一个符合最流行的数据库管理系统进行整合。

  • FOSRestBundle来处理我的API的剩余部分(做注解,身体监听器,用于支持JMSSerializer响应汽车等格式最大)。

  • KnpGaufretteBundle,因为我想允许改变我快速存储BLOB文件的方式。

第一个解决方案设想:BASE64

我首先想到的,因为我在想JSON每次,是EN code以base64所有传入的图片,我的API里面,并将其储存然后去code他们。

My first thought, because I was thinking JSON everytime, was to encode all the incoming images in base64, then decode them inside my API and store them.

这种解决方案的优点是,可以与其他数据一起传送的图像。例如在一个API调用上传整个用户的个人资料。不过,我看到,在Base64编码的图像让他们其初始大小的33%的速度增长。我送3的图像后不希望我的用户成为了移动数据流量。

The advantage with this solution is that you can pass images along with other data. For instance upload a whole user's profile in one API call. But I read that encoding images in base64 make them grow by 33% of their initial size. I did not wanted my users to be out of mobile data after sending 3 images.

二的解决方案设想:形式

然后我想用上述形式。但我不知道怎么我的客户会同时发送JSON数据(例如 {姓氏:利兹} )和图像数据(例如图像/ PNG 之一)。我知道,你可以处理一个内容类型:多重/ form-data的但仅此而已。

Then I thought using forms as described above. But I did not know how my clients could send both JSON data (for instance {"last_name":"Litz"}) and image data (for instance image/png one). I know that you can deal with an Content-Type: multipart/form-data but nothing more.

另外,我没有使用形式从一开始我的API和我想它是在我所有的code均匀。 [微型编辑:HOHO,这是我刚刚发现,这里]

Plus I was not using forms in my API since the beginning and I wanted it to be uniform in all my code. [mini-edit: hoho, something I just discovered, here]

第三和最后的解决方案:使用HTTP ..

然后,一到晚上,启示。我使用内容类型:应用程序/ JSON 为发送JSON数据。为什么不使用图像/ * 发送图像?很容易,我搜索了天,这个思想来之前。这是我做的(简化code)。让我们假设用户在调用 PUT / API / ME /图片内容类型:图像/ *

Then, one night, the revelation. I'm using Content-Type: application/json for send JSON data. Why not use image/* to send images? So easy that I searched for days before coming with this idea. This is how I did it (simplified code). Let suppose that the user is calling PUT /api/me/image with a Content-Type: image/*


  1. UserController中:: getUserImageAction(请求$要求) - 捕请求

  1. UserController::getUserImageAction(Request $request) - Catching the Request

    // get the service to handle the image
    $service = $this->get('service.user_image');
    $content = $request->getContent();
    $userImage = $service->updateUserImage($user, $content);

    // get the response from FOSRestBundle::View
    $response = $this->view()->getResponse();
    $response->setContent($content);
    $response->headers->set('Content-Type', $userImage->getMimeType());

    return $response;


  • UserImageService :: updateUserImage($用户,$内容) - 业务逻辑(我把这里的一切是simplier阅读)

  • UserImageService::updateUserImage($user, $content) - Business Logic (I put everything here to be simplier to read)

        // Create a temporary file on the disk
        // the temp file will be delete at the end of the script
        // see http://www.php.net/manual/en/function.tmpfile.php
        $file = tmpfile();
        if ($file === false) 
            throw new \Exception('File can not be opened.');
    
        // Put content in this file
        $path = stream_get_meta_data($file)['uri'];
        file_put_contents($path, $content);
    
        // the UploadedFile of the user image
        // referencing the temp file (used for validation only)
        $uploadedFile = new UploadedFile($path, $path, null, null, null, true);
    
        // the UserImage to return
        $userImage = $user->getUserImage();
        if (is_null($userImage))
        {
            $userImage = new UserImage();
            $userImage->setOwner($user); 
            // auto persist with my configuration
            // plus generation of a unique ID that allows
            // me to retrieve the image at anytime
            $userImage->setKey(/*random string*/);
        }
    
        // fill the UserImage properties
        $userImage->setImage($uploadedFile);
        $userImage->setMimeType($uploadedFile->getMimeType());
    
        /** @var ConstraintViolationInterface $validationError */
        if (count($this->getValidator()->validate($userImage)) > 0)
            throw new \Exception('Validation');
    
        // if no error we can write the file definitively
        // [KnpGaufretteBundle code to store on disk]
        // [use the UserImage::key to store]
        $this->getEntityManager()->flush();
    
        return $userImage;
    


  • 这篇关于通过上传使用Symfony2的和放API的图像文件; FOSRESTBundle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆