Symfony-ファイルをMongoDB GridFSにアップロードする

GridFSは、大きなファイルを保存するためのMongoDB仕様です。 この記事では、ファイルをGridFSに簡単にアップロードし、データベースから抽出してブラウザーに表示する方法を説明します。



しかし、始める前に、Kridina ChodorowのGridFSの仕組みを簡単に説明します。

GridFSは、大きなファイルを小さな断片に分割します。 ピースは1つのコレクション(fs.chunks)に保存され、ファイルのメタデータは別のコレクション(fs.files)に保存されます。 ファイルに要求を行うと、GridFSはスライスを使用してコレクションに要求を行い、ファイル全体を返します。



もちろん、PHP用MongoDBドライバーには、GridFSからファイルを保存および取得するために使用できるいくつかのクラスが付属しています。



この記事で説明したGridFSの利点のいくつか:





GridFSドキュメントの作成



簡単なアップロードドキュメントから始めましょう。



namespace Dennis\UploadBundle\Document; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; /** * @MongoDB\Document */ class Upload { /** @MongoDB\Id */ private $id; /** @MongoDB\File */ private $file; /** @MongoDB\String */ private $filename; /** @MongoDB\String */ private $mimeType; /** @MongoDB\Date */ private $uploadDate; /** @MongoDB\Int */ private $length; /** @MongoDB\Int */ private $chunkSize; /** @MongoDB\String */ private $md5; public function getFile() { return $this->file; } public function setFile($file) { $this->file = $file; } public function getFilename() { return $this->filename; } public function setFilename($filename) { $this->filename = $filename; } public function getMimeType() { return $this->mimeType; } public function setMimeType($mimeType) { $this->mimeType = $mimeType; } public function getChunkSize() { return $this->chunkSize; } public function getLength() { return $this->length; } public function getMd5() { return $this->md5; } public function getUploadDate() { return $this->uploadDate; } }
      
      





このリストの重要な部分は@MongoDB \ Fileアノテーションです。 彼女はDoctrine MongoDB ODMに、ドキュメントをGridFSを使用して保存する必要があり、MongoGridFSFileクラスのインスタンスが$ fileプロパティに含まれていることを伝えます。



$ chunkSize$ length$ md5および$ uploadDateプロパティは、MongoDBドライバーによって自動的に入力されるため、セッターを必要としません。



ファイルアップロード処理



例として、フォームビルダーを使用する単純なコントローラーを使用して、 fileタイプのフィールドを持つフォームを作成します



 namespace Dennis\UploadBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class UploadController extends Controller { public function newAction(Request $request) { $form = $this->createFormBuilder(array()) ->add('upload', 'file') ->getForm(); if ($request->isMethod('POST')) { $form->bind($request); // ... } return array('form' => $form->createView()); } }
      
      





私の目標は、ファイルシステムの周りの複数のファイル転送を回避するために、ダウンロード後に/ tmpフォルダーから直接データベースにファイルを保存することです。 これを行うには、 $ form-> getData()を使用してフォームから送信されたデータを抽出し、 UploadedFileオブジェクトを取得します。 エンティティを使用する場合、 UploadedFileオブジェクトはエンティティのプロパティの値から取得できます。このプロパティの値は、フォームビルダーでfileタイプのフィールドとして指定されます



UploadedFileオブジェクトには、グローバルPHP変数$ _FILESのデータに基づいているため、一時フォルダーからデータベースに直接ファイルを追加するために必要なすべての情報が含まれています。



 use Dennis\UploadBundle\Document\Upload; public function newAction(Request $request) { // ... $data = $form->getData(); /** @var $upload \Symfony\Component\HttpFoundation\File\UploadedFile */ $upload = $data['upload']; $document = new Upload(); $document->setFile($upload->getPathname()); $document->setFilename($upload->getClientOriginalName()); $document->setMimeType($upload->getClientMimeType()); $dm = $this->get('doctrine.odm.mongodb.document_manager'); $dm->persist($document); $dm->flush(); }
      
      





必要な情報がすべて揃ったので、 Uploadオブジェクトを作成して、一時ファイルへのパスを$ fileプロパティに渡すことができます。 UploadedFileオブジェクトは、ファイルに関する追加情報も提供します。その一部は、MIMEタイプやファイル名など、 アップロードドキュメントに追加できます。 この段階では、ドキュメントをデータベースに保存する準備ができており、ODMから予想されるように、これはpersist()およびflush()を使用して行われます。



ダウンロードしたファイルをGridFSから抽出する



データベースにファイルができたので、ファイルを取得してブラウザに表示する方法を見てみましょう。



上記で説明したコントローラーに、別のメソッドを追加します。



 /** * @Route("/{id}", name="upload_show") */ public function showAction($id) { $upload = $this->get('doctrine.odm.mongodb.document_manager') ->getRepository('DennisUploadBundle:Upload') ->find($id); if (null === $upload) { throw $this->createNotFoundException(sprintf('Upload with id "%s" could not be found', $id)); } $response = new Response(); $response->headers->set('Content-Type', $upload->getMimeType()); $response->setContent($upload->getFile()->getBytes()); return $response; }
      
      





ご覧のとおり、かなり簡単です。 MongoDBによって生成されたidパラメーターはURLで指定する必要があり、データベースからアップロードドキュメントを取得するために使用されます。 ファイルを出力するには、 Content-Typeを使用してResponseクラスのオブジェクトを作成します。これは、 アップロードドキュメントの$ mimeTypeプロパティから取得します。 そして、 getBytes()メソッドを使用して、 $ fileプロパティから出力用のコンテンツを取得します



ストリームリソースとStreamedResponse



バージョン1.3.0-beta1以降、MongoDBドライバーは、ファイルのストリームリソースを返すgetResource()メソッドをサポートします。 これにより、通常のResponseの代わりにStreamedResponseオブジェクトを使用できます。 StreamedResponseを使用すると、 コールバックを使用して、クライアントにコンテンツをストリーミングできます (ブラウザ-約Per。)。 次のようになります。



 public function showAction($id) { // ... $response = new StreamedResponse(); $response->headers->set('Content-Type', $upload->getMimeType()); $stream = $upload->getFile()->getResource(); $response->setCallback(function () use ($stream) { fpassthru($stream); }); return $response; }
      
      





今のところすべてです。 次の記事では、 アップロードドキュメントとエンティティを組み合わせる方法について説明します。



-これは、 MongoDB GridFSへのファイルのアップロードの記事の無料翻訳です。 2番目の部分の翻訳が計画されています。



All Articles