2017-10-31 32 views
0

私はこのトピックに関する質問を読んできましたし、これまで重要だった回答も見ましたが、現在この同じ問題に関連するプログラミング上の問題が発生しています。私はSymfony 3フレームワークを使用して複数のファイルをアップロードしようとしています。本当に挑戦しています。私はこれを行うための次のコードを持っています。 最初はフォームタイプで使用しています:Symfony 3複数のファイルアップロード

class ProductImageType extends AbstractType 
{ 
/** 
* Build the form 
* @param None 
* @return void 
**/ 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('file', FileType::class, array('attr'=>array('class'=>'form-control'), 'multiple' => true)); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(
     array(
      'data_class' => 'AppBundle\Entity\ProductImages', 
     ) 
    ); 
} 

public function getName() 
{ 
    return 'ProductImageType'; 
} 
} 

これは、使用してエンティティアムです:

class ProductImages 
{ 
/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="productSku", type="string", length=15, unique=true) 
*/ 
private $productSku; 

/** 
* @var string $file 
* 
* @ORM\Column(name="file", type="string", length=255) 
* @Assert\NotBlank(message="You must select at least one valid image file.") 
* 
*/ 
private $file; 

/** 
* @var int 
* 
* @ORM\Column(name="dateCreated", type="integer", nullable=true) 
*/ 
private $dateCreated; 


/** 
* Get id 
* 
* @return int 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set productSku 
* 
* @param string $productSku 
* 
* @return productImages 
*/ 
public function setProductSku($productSku) 
{ 
    $this->productSku = $productSku; 

    return $this; 
} 

/** 
* Get productSku 
* 
* @return string 
*/ 
public function getProductSku() 
{ 
    return $this->productSku; 
} 

/** 
* Set images 
* 
* @param UploadedFile $file 
* 
* @return productImages 
*/ 
public function setFile($file = null) 
{ 
    $this->file = $file; 

    return $this; 
} 

/** 
* Get images 
* 
* @return string 
*/ 
public function getFile() 
{ 
    return $this->file; 
} 

/** 
* Set dateCreated 
* 
* @param integer $dateCreated 
* 
* @return productImages 
*/ 
public function setDateCreated($dateCreated) 
{ 
    $this->dateCreated = $dateCreated; 

    return $this; 
} 

/** 
* Get dateCreated 
* 
* @return int 
*/ 
public function getDateCreated() 
{ 
    return $this->dateCreated; 
} 
} 

をそして、このコントローラは、ファイルのアップロードを処理するために使用しています:

public function uploadAction(Request $request) 
{ 
    $files = $request->files->get('product_image'); 
    $sku = $request->request->get('productSku'); 
    $uploaded = false; 
    $message = null; 

    $count = 0; 
    $image_files = []; 

    $uploadDir = $this->getParameter('products_images_directory') . DIRECTORY_SEPARATOR . $sku . DIRECTORY_SEPARATOR; 
    $mimeTypes = array('image/jpeg','image/jpg','image/png','image/gif','image/bmp'); 
    $doctrine = $this->getDoctrine()->getManager(); 

    if(!empty($files)) 
    { 
     foreach($files as $file => $v) 
     { 
      $filename[$count] = $sku . '_' . $count . '.' . $v[$count]->guessExtension(); 
      $image_files[$count]['file'] = $filename[$count]; 
      $image_files[$count]['file_size'] = $v[$count]->getClientSize(); 
      Dump($image_files);die; 
      /**if(!is_dir($uploadDir) && !file_exists($uploadDir . $filename)) 
      { 
       mkdir($uploadDir, 0775, TRUE); 

       if($value[$count]->move($uploadDir, $filename)) 
       { 
        $productImages = new ProductImages(); 

        $productImages->setProductSku($sku); 
        $productImages->setFile($filename[$i]); 
        $productImages->setDateCreated(strtotime(date('y-m-d h:i:s a'))); 

        $doctrine->persist($productImages); 
        $doctrine->flush(); 
       } 

      } 
      **/ 
      $count++; 
     } 
     Dump($image_files);die('Action ended!'); 
     if($count>1) 
     { 
      $uploaded = TRUE; 
      $message = "All Images have been uploaded & saved!!"; 
     } 

    } 
    Dump($message);die; 
    return (new JsonResponse(
     [ 
      'uploaded'=>$uploaded, 
      'message'=>$message 
     ] 
    )); 

} 

私はDropzone.jsを使ってフロントエンドを処理しようとしていましたが、統合前にすべてが正常に動作することを確認しなければなりませんでした。 foreach(...)を使用して複数の画像をアップロードしようとすると、画像の1つのみがアップロードされることがわかりました。 Dump(...)のコンテンツの$request->request->get(...)複数のファイルが表示されていますが、foreach(...)は2番目または3番目のファイルではない最初の配列の内容のみを取り込みます。それを出す。誰かが6番目の目を助けてくれますか?

+0

データを受信するにはフォームタイプを使用する必要があります。 関連するコードのみを掲載できますか?私はあなたがforeachの問題を抱えている場合、エンティティのコードを必要とせず、コメントなどのコードを必要としないことを意味します...私たちがあなたを理解し助けてくれるのは単なる難しいことです。 – goto

+0

[Symfony2で複数ファイルをアップロードする]の可能な複製(https://stackoverflow.com/questions/6736946/multiple-file-upload-with-symfony2) – goto

答えて

0

多くの睡眠不足の時間の後、私は最終的に、複数の(画像)ファイルアップロードのためにsymzoneをdropzone.jsで動作させることができました。これはもちろん、他のタイプのファイルで動作するように微調整されることがあります。

マイエンティティ:

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* productImages 
* 
* @ORM\Table(name="product_images") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\productImagesRepository") 
*/ 

class ProductImages 
{ 

/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
private $id; 

/** 
* @var string 
* 
* @ORM\Column(name="productSku", type="string", length=15, unique=true) 
*/ 
private $productSku; 

/** 
* 
* @ORM\Column(name="files", type="string", length=255) 
* @Assert\NotBlank(message="You must select at least one valid image 
file.") 
* 
*/ 
private $files; 


/** 
* @var int 
* 
* @ORM\Column(name="dateCreated", type="integer", nullable=true) 
*/ 
private $dateCreated; 

/** 
* Class Contructor 
* 
* @param array $options 
* @return void 
*/ 
public function __construct() 
{} 

/** 
* Get id 
* 
* @return int 
*/ 
public function getId() 
{ 
    return $this->id; 
} 

/** 
* Set productSku 
* 
* @param string $productSku 
* 
* @return productImages 
*/ 
public function setProductSku($productSku = NULL) 
{ 
    $this->productSku = $productSku; 

    return $this; 
} 

/** 
* Get productSku 
* 
* @return string 
*/ 
public function getProductSku() 
{ 
    return $this->productSku; 
} 

/** 
* Set image Files 
* 
* @param String $files 
* 
* @return productImages 
*/ 
public function setFiles($files = NULL) 
{ 
    $this->files = (string)$files; 

    return $this; 
} 

/** 
* Get image Files 
* 
* @return string 
*/ 
public function getFiles() 
{ 
    return $this->files; 
} 

/** 
* Set dateCreated 
* 
* @param integer $dateCreated 
* 
* @return productImages 
*/ 
public function setDateCreated($dateCreated) 
{ 
    $this->dateCreated = $dateCreated; 

    return $this; 
} 

/** 
* Get dateCreated 
* 
* @return int 
*/ 
public function getDateCreated() 
{ 
    return $this->dateCreated; 
} 
} 

フォームタイプ:

class ProductImageType extends AbstractType 
{ 
/** 
* Build the form 
* @param None 
* @return void 
**/ 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('files', FileType::class, array('attr'=>array('class'=>'form-control'), 'multiple' => true)); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(
     array(
      'data_class' => 'AppBundle\Entity\ProductImages', 
     ) 
    ); 
} 

public function getName() 
{ 
    return 'ProductImageType'; 
} 

} 

コントローラーアクション:

/** 
* Upload Product Image(s) 
* 
* @Route("/admin/products/upload", name="uploadProductImageRoute") 
* 
* @access public 
* @param Request $request 
* @return Object 
**/ 
public function uploadInitAction(Request $request) 
{ 

    $files = $request->files->get('files'); 
    $sku = $request->request->get('productSku'); 

    $uploaded = false; 
    $message = null; 
    $count = $countValid = 0 ; 

    $mimeTypes = array('jpeg','jpg','png','gif','bmp'); 

    if(!empty($files)) 
    { 
     for($count; $count < count($files); $count++) 
     { 
      if(in_array($files[$count]->guessClientExtension(), $mimeTypes)) 
       $countValid++; 
     } 
     if($countValid == count($files)) 
      $uploaded = $this->uploadExec($sku, $files); 
    } 

    if($uploaded) 
     $message = "All Images have been uploaded & saved!!"; 
    else 
     $message = "Selected File(s) weren't uploaded!!"; 


    return $this->json(
     [ 
      'uploaded' => $uploaded, 
      'message' => $message 
     ] 
    ); 

} 

/** 
* Performs Actual File Upload 
* 
* @param string $sku 
* @param array $args 
* @return Boolean 
* 
*/ 
private function uploadExec($sku, $args = array()) 
{ 
    /** 
    * Make sure this is a new product without images saved yet 
    */ 
    if($this->hasImages($sku))return FALSE; 

    $count = 0; 
    $image_files = []; 
    $doctrine = $this->getDoctrine()->getManager(); 

    $uploadDir = $this->getParameter('products_images_directory') . DIRECTORY_SEPARATOR . $sku . DIRECTORY_SEPARATOR; 

    if(!is_dir($uploadDir)) 
    { 
     mkdir($uploadDir, 0775, TRUE); 
    } 

    if(!empty($args) && count($args) > 0) 
    { 
     for($count; $count < count($args); $count++) 
     { 
      $filename[$count] = $sku . '_' . $count . '.' . $args[$count]->guessClientExtension(); 

      if(!file_exists($uploadDir . $filename[$count])) 
      { 
       if($args[$count]->move($uploadDir, $filename[$count])) 
       { 
        $image_files[$count]['file'] = $filename[$count]; 
        $image_files[$count]['file_size'] = $args[$count]->getClientSize();  
        //$image_files[$count]['file_location'] = $uploadDir; 
       } 
      } 
     } 

     $jsonEncodeFiles = json_encode($image_files); 
     /* 
     * Persist Uploaded Image(s) to the Database 
     */ 
     $productImages = new ProductImages(); 
     $productImages->setProductSku($sku); 
     $productImages->setFiles($jsonEncodeFiles); 
     $productImages->setDateCreated(strtotime(date('y-m-d h:i:s a'))); 

     $doctrine->persist($productImages); 
     $doctrine->flush(); 

     if(NULL != $productImages->getId())return TRUE; 
    } 

    return FALSE; 
} 

テンプレート:

{{ form_start(uploadForm, {'action':path('uploadProductImageRoute'), 'method' : 'POST', 'attr': {'id' : 'form-with-dropzone', 'class' : 'form-horizontal dropzone' }}) }} 
<input type="hidden" name="productSku" value="{{ sku }}" /> 
<div class="row"> 
    <div class="dropzone-previews"></div> 
    <div class="fallback"> 
     {{ form_widget(uploadForm.files) }} 
    </div> 
</div> 
{{ form_end(uploadForm) }} 
<div class="row no-margin-right no-margin-left"> 
<div class="form-group no-margin-right no-margin-left" style="margin-top: 30px;"> 
    <div class="pull-right"> 
     <button id="submit" type="submit" class="btn btn-sm btn-inverse"><i class="ace-icon typcn typcn-location-arrow-outline align-top bigger-115"></i>&nbsp;Upload Image(s)</button> 
    </div> 
    </div> 
</div> 

Javascriptを:

Dropzone.options.formWithDropzone = { 
     autoProcessQueue: false, 
     uploadMultiple: true, 
     paramName: "files", 
     parallelUploads: 10, 
     maxFiles: 10, 
     addRemoveLinks: true, 
     acceptedFiles: 'image/*', 
     init: function(){ 
      var dropZone = this; 

      $('#submit').click(function(e){ 
       e.preventDefault(); 
       e.stopPropagation(); 
       dropZone.processQueue(); 
      }); 

      dropZone.on("success", function(file, response) { 
       if(dropZone.getAcceptedFiles().length > 0){ 
        $.gritter.add({ 
         title : 'Upload Complete', 
         text : response.message + '\n\nA total of: ' + dropZone.getAcceptedFiles().length + ' images uploaded successfully!', 
         class_name : 'gritter-success' 
        }) 
       }else{ 
        $.gritter.add({ 
         title : 'Upload Incomplete', 
         text : response.message, 
         class_name : 'gritter-error' 
        }) 
       } 
    }); 
    } 
} 

これは私がそれを望んだ何をしてもらうために、複雑で不必要なエンティティ・リレーションシップ・マッピングを作成する必要はありませんでした。 この上で作業している間、私は、アップロードされたファイル(複数可)のMIMEタイプをチェックするUploadedFileクラスのgetMimeType()メソッドを使用するとエラーになったことに気づい: FileNotFoundException in MimeTypeGuesser.php line 123: The file "F:\wamp2.5\tmp\php....tmp" does not exist

私が変更した後ただし、エラーがdisappeard方法getMimeType() to guessClientExtension()

将来、私はこれが誰かに多くの時間を節約することを願っています。

関連する問題