通过URL输入设置Symfony上传文件

Via an XML import I'm getting also an url link to jpg images on an external server. I want to copy the images. I'm tried to do this via UploadedFile() function in Symfony to then add them in my entity.

Via the following code I want to add the url image in the Symfony image object.

$f = new UploadedFile();
$f->openFile($imageUrl);

So after opening the file I want to add them in my image entity.

$image = new image();
$image->setFile($f);

This entity contains the following file parameters:

/**
* Sets file.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
*/
public function setFile(UploadedFile $file = NULL) {
    $this->file = $file;
}

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

Then I get the error that arguments are missing. But with an from it works with the following code:

$image = new image();
$image->setFile($request->files->get('images'));

To download a file from a url with php you will need to take a look at : http://php.net/manual/fr/function.file-put-contents.php

With Symfony File object, To persist an Image if you have an image entity :

namespace AppBundle\Entity;

use Symfony\Component\HttpFoundation\File\File;

class Image
{
    protected $file;

    public function setFile(File $myFile = null)
    {
        $this->file = $myFile;
    }

    public function getFile()
    {
        return $this->file;
    }
}

if you want to specify some validation rules using annotations

use Symfony\Component\Validator\Constraints as Assert;

class Image
{
    /**
     * @Assert\File(
     *     maxSize = "1024k",
     *     mimeTypes = {"image/jpeg", "image/png"},
     *     mimeTypesMessage = "Please upload a valid image"
     * )
     */
    protected file;
}

Then the upload function that move the file

public function upload(File $file)
{
    //generate unique filename
    $fileName = md5(uniqid()).'.'.$file->guessExtension();

    //Set other entity attribute here

    //move the file
    $file->move($targetDirectory, $fileName);

    return $fileName;
}

And then in controller do something like this

$em = $this->getDoctrine()->getManager();
$image = new Image();
$file = file_get_contents('http://www.example.com/');
$image->setFile($file);
$image->upload();
//Maybe persist your entity if you need it
$em->persist($image);
$em->flush();

This is a quick example to help you, might not work with copy past (and it's not the purpose).

Take a look at : http://symfony.com/doc/current/controller/upload_file.html

I use vich uploader bundle (https://github.com/dustin10/VichUploaderBundle) to uploads images, the bundle provides a way to upload images from forms. I had the same use case than you. I have to import images from a xml.

I use vich service (vich_uploader.upload_handler) to do that from a xml:

Entity:

namespace AppBundle;

use Doctrine\ORM\Mapping AS ORM;
use Symfony\Component\HttpFoundation\File\File;

/**

 * @ORM\Table(name="entity")
 * @Vich\Uploadable
 */
class Entity
{

/**
 * @ORM\Column(type="string", nullable=true)
 */
private $image;

/**
 * @Vich\UploadableField(mapping="test_image", fileNameProperty="image")
 * @var File
 */
private $imageFile;


/**
 * @return File
 */
public function getImageFile()
{
    return $this->imageFile;
}

/**
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
 */
public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}
}

service:

<?php

namespace AppBundle;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Handler\UploadHandler;

class ExternalImageUploader
{

private $uploadHandler;
private $kernelRootDir;


public function __construct(UploadHandler $uploadHandler, $kernelRootDir)
{
    $this->uploadHandler = $uploadHandler;
    $this->kernelRootDir = $kernelRootDir;
}

public function copyExternalFile($url, $entity)
{

    $newfile = $this->kernelRootDir.'/../web/uploads/test.jpg';

    copy($url, $newfile);
    $mimeType = mime_content_type($newfile);
    $size = filesize ($newfile);
    $finalName = md5(uniqid(rand(), true)).".jpg";

    $uploadedFile = new UploadedFile($newfile,$finalName,$mimeType, $size);

    $entity->setImageFile($uploadedFile);
    $this->uploadHandler->upload($entity,'imageFile');


}
}

services.xml

<service id="app.external_image_uploader" class="AppBundle\ExternalImageUploader">
        <argument type="service" id="vich_uploader.upload_handler" />
        <argument>%kernel.root_dir%</argument>
    </service>