簡體   English   中英

Symfony 3多個文件上傳

[英]Symfony 3 Multiple File Uploads

我已經閱讀了有關該主題的問題,並且到目前為止已經看到了很重要的答復,但是目前正遇到與此相同問題相關的一些編程困難。 我正在嘗試使用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';
}
}

這是實體Am正在使用:

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(...)上傳多張圖片時,只有其中一張圖片被上傳。 $request->request->get(...)內容的Dump(...)上,我看到選擇了多個文件,但是foreach(...)僅獲取第一個數組的內容,而沒有第二或第三...我知道問題是在這種情況下,但我無法弄清楚。 請問有人有第六只眼睛可以協助嗎?

經過數小時的不眠之夜,我終於能夠使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>

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

無需進行復雜且不必要的實體關系映射,即可完成我想要的操作。 在處理此問題時,我意識到使用UploadedFile類的getMimeType()方法來檢查上載文件的getMimeType()類型會導致錯誤: FileNotFoundException in MimeTypeGuesser.php line 123: The file "F:\\wamp2.5\\tmp\\php....tmp" does not exist

然而,i之后的錯誤disappeard改變方法getMimeType()guessClientExtension()

希望以后能節省很多時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM