10

JQueryライブラリの新しい実装を試しました:dropzone.js

このライブラリは、ドラッグ アンド ドロップ ソリューションを備えた優れたマルチ アップロード インターフェイスを提供します。

Symfony のマルチアップロードシステムは簡単ではないようです。

私はこのエラーを持っています:

Error: Cannot use object of type Symfony\Component\HttpFoundation\File\UploadedFile as array in /vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php line 87

私のエンティティファイル:

/**
* @ORM\Entity
* @ORM\Table(name="media__file")
* @ORM\HasLifecycleCallbacks
*/
class File
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
public $id;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank
 */
public $name;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
public $path;

/**
 * @Assert\File(maxSize="6000000")
 */
public $file;

public function getAbsolutePath()
{
    return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
}

public function getWebPath()
{
    return null === $this->path ? null : $this->getUploadDir().'/'.$this->path;
}

protected function getUploadRootDir()
{

    return __DIR__.'/../../../../../web/'.$this->getUploadDir();
}

protected function getUploadDir()
{

    return 'uploads/files';
}

 /**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{
    if (null !== $this->file) {
        $this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
    }
}

/**
 * @ORM\PostPersist()
 * @ORM\PostUpdate()
 */
public function upload()
{
    if (null === $this->file) {
        return;
    }


    $this->file->move($this->getUploadRootDir(), $this->path);

    unset($this->file);
}

/**
 * @ORM\PostRemove()
 */
public function removeUpload()
{
    if ($file = $this->getAbsolutePath()) {
        unlink($file);
    }
}

私のコントローラー FileController :

/**
 * @Route("/admin/media/upload")
 * @Template()
 */
public function uploadsAction (){

    $file = new File();

    $form = $this->createForm(new \Tperroin\Bundle\MediaBundle\Form\FileUploadType(), $file);

    if ($this->getRequest()->isMethod('POST')) {
        $form->bind($this->getRequest());

        if ($form->isValid()) {

            $em = $this->getDoctrine()->getManager();

            $em->persist($file);
            $em->flush();

            return $this->redirect($this->generateUrl('tperroin_home_default_index'));
        }
    }

return array('form' => $form->createView());
}

そして最後に私の小枝のテンプレート:

<div class="widget-content">

        <form action="{{ url('tperroin_media_file_uploads') }}" method="post" {{ form_enctype(form) }} class="dropzone">

            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </form>

    </div>

編集 :

フォームタイプ:

class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('file', 'file');
}
public function getName()
{
    return 'file';
}
}

私のコードの何が問題になっていますか? UploadedFile と配列に問題があることはわかっていますが、解決方法がわかりません。

すべてをありがとう !

編集 :

多分このリンクは誰かを助けることができます、私はこれを再現できません:

Symfony2 での複数ファイルのアップロードに関する問題

新しい uploadAction 関数で編集:

/**
* @Route("/upload/process", name="upload_media")
*/
   public function uploadAction()
   {
   $request = $this->get('request');
   $files = $request->files;       

   $directory = $this->get('kernel')->getRootDir() . '/../web' . $this->getRequest()->getBasePath() . '/files/';

   foreach ($files as $uploadedFile) {

       $name = $uploadedFile->getClientOriginalName();
       $file = $uploadedFile->move($directory, $name);

       $upload = new File($name);

       $em = $this->get('doctrine')->getManager();

       $em->persist($upload);

       $em->flush();


   }

   return $this->redirect($this->generateUrl('tperroin_media_default_index'));
   }
4

3 に答える 3

8

FileUploadTypeまず第一に、Twig テンプレートでは実際には your を使用しません。フォームを手動で作成actionし、コントローラーで定義した URL へのパスを設定します。テンプレートに渡すフォーム ビューから使用するのは、form_enctype. しかし、ほとんどの複数ファイル アップローダーと同様に、Dropzone は画像をアップロードするための独自のリクエストを偽造しているようです。

つまり、受信データも手動で処理する必要があります。

/**
 * @Route("/admin/media/upload")
 * @Template()
 */
public function showUploadAction()
{
    // just show the template
    return [];
}

/**
 * @Route("/admin/media/upload/process", name="upload_media")
 */
public function uploadAction()
{
    $request = $this->get('request');
    $files = $request->files;

    // configuration values
    $directory = //...

    // $file will be an instance of Symfony\Component\HttpFoundation\File\UploadedFile
    foreach ($files as $uploadedFile) {
        // name the resulting file
        $name = //...
        $file = $uploadedFile->move($directory, $name);

        // do something with the actual file
        $this->doSomething($file);
    }

    // return data to the frontend
    return new JsonResponse([]);
}

このメソッドuploadActionは、FileBagSymfony のリクエストから を取得し、それを反復処理して、結果のファイルに対してカスタム ロジックを実行します。もちろん、Fileエンティティの格納は自分で処理する必要があります。

テンプレートは次のようになります。

<form action="{{ path('upload_media') }}" method="post" class="dropzone">
    <div class="fallback">
        <input name="file" type="file" multiple />
    </div>
</form>


この質問のおかげで、私は Dropzone アップローダに注目し、 OneupUploaderBundleそれをサポートするようになりました。したがって、上記のいくつかの手順を簡素化するこのバンドルを使用できます。

于 2013-09-18T11:12:52.533 に答える
1

symfony では、すべてのフォームに csrf-token が含まれている必要があります。フォームに含まれていないため、symfony は「ファイル」フィールドを csrf-token として使用しようとし、エラーをスローします。この問題を解決するための最初のステップは、フォーム要素に次のスニペットを含む csrf-token をレンダリングすることです。

{{ form_widget(form) }}

次に、複数のファイルを処理できるようにエンティティを変更する必要があります。これは、1 対多の関係 (アップロード (1) からファイル (多)) を実装することで実行できます。

于 2013-09-16T16:08:15.373 に答える
0

Symfony でエラーが発生した場合

Error: Call to a member function move() on a non-object

変更してみる

$files = $request->files

$files = $request->files->get('file');
于 2015-03-05T08:31:12.477 に答える