1

实现了通过文档下载文件。但是当我决定使用'multiple'时,发出一个错误

"Catchable Fatal Error: Argument 1 passed to Kulabuhov\MainBundle\Entity\Photo::setFile() must be an instance of Symfony\Component\HttpFoundation\File\UploadedFile, array given," 

. 我知道不是 Object 传递了一个数组。但是如何在不破坏您在文档中编写的任何内容的情况下实现多个文件上传?

$builder
            ->add('file','file',['multiple'=>true])
            ->add('article')
        ;
4

2 回答 2

1

您提供了很少的代码来说明您如何使用 Doctrine 遵循文件上传功能,这将很有帮助,因为有十几种方法可以处理文件命名约定的执行方式,而且您甚至没有真正展示自己的尝试修改您正在处理多个文件上传的实体,但我会为您试一试。这是假设您已经按照所有说明进行到最后。

当您按照说明操作时,您可能创建了一个setFile函数,如下所示:

public function setFile(UploadedFile $file = null)
{
    $this->file = $file;
    // check if we have an old image path
    if (isset($this->path)) {
        // store the old name to delete after the update
        $this->temp = $this->path;
        $this->path = null;
    } else {
        $this->path = 'initial';
    }
}

UploadedFile但是当然,您正在向函数提交一个对象数组,该函数与它需要setFile的参数不匹配。UploadedFile您也只为路径存储一个字符串,因此您也必须修复它。

因此,首先您应该将$path变量类型从 a更改string为某种类型的数组。假设您不需要与每个文件关联的太多数据,并且文件名中永远没有逗号,那么让我们坚持使用simple_array

/**
 * @ORM\Column(name="paths", type="simple_array")
 */
private $paths = array();

现在您需要为该file属性声明一个数组:

/**
 * @Assert\File(maxSize="60000000")
 */
private $files = array();

现在你必须改变你的setFile函数来处理数组输入(让我们重命名setFiles为一致性):

public function setFiles($files)
{
    $this->files = $files;
    // In this scenario, we'll delete the old batch of uploads, so store it in $temp
    if (!empty($this->paths)) {
        $this->temp = $this->getAbsolutePaths();
    }
    $this->paths = array();
}

并且getFiles

public function getFiles()
{
    return $this->files;
}

现在你的新upload()功能:

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

    // Now we have to iterate through each file object
    foreach ($this->getFiles() as $file) {
        // Change $tempPath to whatever random filename strategy you use
        $tempPath = sha1(uniqid(mt_rand(), true)) . '.' . $file->guessExtension();
        $file->move(
            $this->getUploadRootDir(),
            $tempPath
        );
        // Now add it to the paths array
        $this->paths[] = $tempPath;
    }

    // Need to delete all of the old files
    foreach ($this->temp as $del) {
        if (is_file($del)) {
            unlink($del);
        }
    }

    // Reset the $files var
    $files = array();
}

然后对于删除,完全删除所有文件:

/**
 * @ORM\PostRemove()
 */
public function removeUpload()
{
    foreach ($this->getAbsolutePaths() as $path) {
        if (is_file($path)) {
            unlink($path);
        }
    }
}

因为当您使用对象时,您现在正在处理一组路径,因此您还必须更新您的 web 和绝对路径函数:

public function getAbsolutePaths()
{
    $out = array();
    foreach ($this->getPaths() as $path) {
        $out[] = $this->getUploadRootDir().'/'.$this->path;
    }
    return $out;
}

public function getWebPath()
{
    $out = array();
    foreach ($this->getPaths() as $path) {
        $out[] = '/' . $this->getUploadDir() . '/' . $this->path;
    }
}

瞧......一旦你更新你的构建器去files而不是file,它应该能够正确处理多个文件上传。即使上面的代码都是未经测试的,这应该给你很多工作。

于 2014-10-22T20:46:48.490 回答
0

问题不在于您的表格,而在于您的模型。setFile()onPhoto方法旨在接收一个,而UploadedFile不是一个数组。如果照片有多个文件,请将关系声明为 OneToMany 并实现一个setFiles()接受数组的函数:

protected $files;

function setFiles(array $files)
{
    $this->files = $files;

    return $this;
}
于 2014-10-22T20:53:07.153 回答