2017-10-31 3 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(...)을 사용하여 여러 개의 이미지를 업로드하려고 할 때 이미지 중 하나만 업로드된다는 것을 발견했습니다. Dump(...) 내용의 $request->request->get(...) 내가 선택한 여러 파일을 볼 수 있지만 foreach(...)은 두 번째 또는 세 번째가 아닌 첫 번째 배열의 내용 만 가져옵니다 ... 문제가이 조건 내에 있음을 알고 있지만 그럴 수는 없습니다. 그것. 누군가 도움을 줄 여섯 번째 눈을 갖습니까?

+0

데이터를 수신하려면 양식 유형을 사용해야합니다. 관련 코드 만 게시 할 수 있습니까? 내 말은 foreach에 문제가있는 경우 엔티티 코드가 필요없고 주석에 코드가 필요 없다는 것을 의미합니다. 우리가 당신을 이해하고 도와주기가 더 어렵습니다. – goto

+0

[Symfony2를 사용한 다중 파일 업로드] (https://stackoverflow.com/questions/6736946/multiple-file-upload-with-symfony2)의 가능한 복제본 – goto

답변

0

많은 불면의 시간이 지나면 마침내 Symfony에서 여러 개의 (이미지) 파일 업로드를 위해 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> 

자바 스크립트 :

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' 
        }) 
       } 
    }); 
    } 
} 

이 내가 그것을가 원하는 것을 할 얻기 위해 복잡하고 불필요한 개체 관계 매핑을 만드는 필요가 없었다. 이 작업하는 동안, i가 UploadedFile 클래스 getMimeType() 방법을 이용하여 업로드 된 파일 (들)의 MIME 유형을 확인하는 것이 실현 오류 결과 : FileNotFoundException in MimeTypeGuesser.php line 123: The file "F:\wamp2.5\tmp\php....tmp" does not exist

그러나 오류 disappeard 내가 변경 후 방법 getMimeType() to guessClientExtension()

미래에는 많은 시간을 절약 할 수 있기를 바랍니다.