私はInstagramのような写真共有アプリのAPIを、ファイルのアップロードにSymfony2、FOSRESTBundle、Vichuploaderを使用してコーディングしています。
GETとPOSTリクエストを回避することはできますが、POSTリクエスト、実際の画像に添付する方法の例が見つかりません私の場合、Vichuploaderがそれを取得して、ファイルのアップロードを手助けできるように。
ちなみに、通常のフォームを使用して言及したスタックを使用すると、問題なくファイルをアップロードできます。
私はまったく同じ問題についての解決策を探していました。これが私がしたことです。
まず、制約について説明します。私は自分のAPIを完全なJSONにして、HTTPプロトコル(ヘッダー、メソッドなど)を利用することを望みました。私は使用することを選択しました:
想定される最初のソリューション:base64
私が最初に考えたのは、JSONを毎回考えていたため、すべての受信画像をbase64でエンコードし、API内でデコードして保存することでした。
このソリューションの利点は、他のデータと共に画像を渡すことができることです。たとえば、1回のAPI呼び出しでユーザーのプロファイル全体をアップロードします。しかし、私はbase64で画像をエンコードすると、初期サイズの33%増加することを読みました。 3つの画像を送信した後、ユーザーがモバイルデータを使いたくないと思いました。
想定される2番目のソリューション:form
次に、上記のフォームを使用することを考えました。しかし、クライアントがJSONデータ(たとえば{"last_name":"Litz"}
)と画像データ(たとえばimage/png
one)の両方を送信する方法を知りませんでした。あなたはContent-Type: multipart/form-data
に対処できることを知っていますが、それ以上は何もできません。
さらに、最初からAPIでフォームを使用しておらず、すべてのコードでフォームを統一したいと考えていました。 [ミニ編集:ほほ、たった今発見した ここ ]
3番目と最後の解決策:HTTPを使用します。
その後、ある夜、啓示。 JSONデータの送信にContent-Type: application/json
を使用しています。 image/*
を使用して画像を送信してみませんか?とても簡単なので、このアイデアを思いつくまでに何日も検索しました。これは私がやった方法です(簡単なコード)。ユーザーがPUT /api/me/image
をContent-Type: image/*
で呼び出しているとします。
UserController :: getUserImageAction(Request $ 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($ user、$ content)-ビジネスロジック(ここにすべてを置いて、読みやすくしました)
// 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;
FOSRestBundleを使用して投稿にフォームタイプを使用します。
たとえば、次のフォームタイプがあるとします。
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('facebook_id',
'text',
array(
'mapped' => FALSE
)
)
->add('profile_pic',
'text',
array(
'mapped' => FALSE
)
)
;
$builder->addValidator(new CallbackValidator(function(FormInterface $form)
{
if ($form["facebook_id"]->getData() === '' || $form["facebook_id"]->getData() === NULL)
{
$form->get('facebook_id')->addError(new FormError('facebook_id should not be empty'));
}
if ($form["profile_pic"]->getData() === '' || $form["profile_pic"]->getData() === NULL)
{
$form->get('profile_pic')->addError(new FormError('profile_pic should not be empty'));
}
})
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
// 'validation_constraint' => $collectionConstraint,
'csrf_protection' => FALSE,
));
}
public function getName()
{
return 'data';
}
次に、JSONをAPIに投稿します。 POSTを実行するときは、ヘッダーを「Content-type = application/json」として設定することを忘れないでください。
JSON構造は次のようになります。
{
"data": {
"facebook_id": "12345",
"profile_pic": "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"
}
}
このjsonが「データ」にラップされるのはなぜですか?フォームタイプにはgetNameに「データ」も含まれているため、検証などを使用します。
私がいつもやっていることは、画像をAPIに送信しながらbase64文字列としてエンコードすることです。
次に、post関数で変換し直します。
$base64 = $form['profile_pic']->getData();
//decode back to image data and create image
$image = imagecreatefromstring(base64_decode($base64));
imagepng($image, $path);
これは、APIコードビットからの完全なアップロードです。これはファイルをアップロードしますが、アップロードされたファイルの検証にまだ問題があります。お役に立てれば。
これはRESTにfosrestバンドルを使用します。
private function addResource(Entity $resource) {
$em = $this->getDoctrine()->getManager();
$em->persist($resource);
$em->flush();
}
private function processForm(Entity $resource)
{
$em = $this->getDoctrine()->getManager();
$uploadedFile = null;
$form = $this->createForm(new EntityForm(), $resource);
foreach ($_FILES as $file) {
$uploadedFile = new UploadedFile(
$file['tmp_name'],
$file['name'], $file['type'],
$file['size'], $file['error'],
$test = false);
}
$submitData = array(
"file" => $uploadedFile,
);
$form->submit($submitData);
if ($form->isValid()) {
$repository = $this->getDoctrine()
->getRepository('AcmeBundle:Product');
$view = View::create();
$resource->setFile($uploadedFile);
// handling api requests
if ($this->getRequest()->getMethod() == "POST") {
$this->addResource($resource);
// store image url
$resource = $repository->find($resource->getId());
if ($resource->getImage()) {
$fs = new Filesystem();
if ($fs->exists($resource->getWebPath())) {
$resource->setImagePath($resource->getWebPath());
}
$this->addResource($resource);
}
$view->setData($resource);
}
return $view;
}
return View::create($form);
}
ポストリクエストを除くアップロードメソッドの例:
public function uploadAction() {
$em = $this->getDoctrine()->getManager();
$document = new Document();
foreach ($_FILES as $file) {
$document->setTitle($file['name']);
$document->file = new UploadedFile($file['tmp_name'],
$file['name'], $file['type'],
$file['size'], $file['error'], $test = false);
$em->persist($document);
$em->flush();
break;
}
$serializer = $this->get('jms_serializer');
$data = $serializer->serialize(
$document, 'json',
SerializationContext::create()->setGroups(array('someGroup')));
return new Response($data);
}
したがって、このアクションは最初にドキュメントをサーバーに格納し、ドキュメントのメタデータとパスを含むjson応答を返します。 Webアプリケーションでさらに処理するために応答を使用しました。
私はVichUploaderに精通していません。上記のコードは、Symfony\Component\HttpFoundation\File\UploadedFileを使用したネイティブSymfony2コードです。
読む: http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html