如何将文件上传添加到Symfony2 DataFixture


How would you add a file upload to a Symfony2 DataFixture?

我似乎无法理解如何将文件上传到DataFixture。我正在尝试为我的固定装置加载的虚拟内容上传一个图像。这似乎是一件有用的事情。

尽管一年前就有人问过这个问题,但似乎没有太多关于如何通过条令数据固定装置上传文件的信息。我只能找到这个帖子。

我一直在寻找,我采取了与ornj略有不同的方法。(可能与Symfony的更新有关。)

我第一次去

use Symfony'Component'HttpFoundation'File'UploadedFile;

然后使用copy()复制图像,因为正如ornj所说,它会移动图像。

copy($art1->getFixturesPath() . '01.jpg', $art1->getFixturesPath() . '01-copy.jpg');

然后使用创建并添加文件

$file = new UploadedFile($art1->getFixturesPath() . '01-copy.jpg', 'Image1', null, null, null, true);
$art1->setFile($file);
$manager->persist($art1);

如果我没有在"UploadedFile"构造函数中将最后一个参数设置为"true",因为它在运行"octrine:fixtures:load"时引发未知错误。此参数为"测试模式是否处于活动状态"。看到它是一个固定装置,设置为测试模式是有意义的。

方法"getFixturesPath()"只检索存储样本图像的路径:

// Entity file
public function getFixturesPath()
{
    return $this->getAbsolutePath() . 'web/uploads/art/fixtures/';
}

"getAbsolutePath()"方法已从Doctrine文件上载中获取。

完整的工作代码:实体:

<?php
//src/User/MyBundle/Entity/Art.php
namespace User/MyBundle/Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'HttpFoundation'File'UploadedFile;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * 
 * Art Entity
 * 
 * @ORM'Entity(repositoryClass="User'MyBundle'Entity'Repository'ArtRepository")
 * @ORM'Table(name="art")
 * @ORM'HasLifecycleCallbacks
 */
class Art
{
    /**
     * @ORM'Id
     * @ORM'Column(type="integer")
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM'Column(type="string", length=100)
     */
    protected $title;
    /**
     * @ORM'Column(type="string", length=255, nullable=true)
     */
    protected $path;
    /**
     * @Assert'File(maxSize="6000000")
     */
    private $file;
    private $temp;
    public function getAbsolutePath()
    {
        return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
    }
    public function getWebPath()
    {
        return null === $this->path ? null : $this->getUploadDir() . '/' . $this->path;
    }
    protected function getUploadRootDir()
    {
        // the absolute directory path where uploaded
        // documents should be saved
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }
    protected function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw up
        // when displaying uploaded doc/image in the view.
        return 'uploads/art';
    }
    public function getFixturesPath()
    {
        return $this->getAbsolutePath() . 'web/uploads/art/fixtures/';
    }
    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    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';
        }
    }
    /**
     * Get file.
     *
     * @return UploadedFile
     */
    public function getFile()
    {
        return $this->file;
    }
    /**
     * @ORM'PrePersist()
     * @ORM'PreUpdate()
     */
    public function preUpload()
    {
        if (null !== $this->getFile()) {
            // do whatever you want to generate a unique filename
            $filename = sha1(uniqid(mt_rand(), true));
            $this->path = $filename . '.' . $this->getFile()->guessExtension();
        }
    }
    /**
     * @ORM'PostPersist()
     * @ORM'PostUpdate()
     */
    public function upload()
    {
        // the file property can be empty if the field is not required
        if (null === $this->getFile()) {
            return;
    }
        // if there is an error moving the file, an exception will
        // be automatically thrown by move(). This will properly prevent
        // the entity from being persisted to the database on error
        $this->getFile()->move($this->getUploadRootDir(), $this->path);
        // check if we have an old image
        if (isset($this->temp)) {
            // delete the old image
            unlink($this->getUploadRootDir() . '/' . $this->temp);
            // clear the temp image path
            $this->temp = null;
        }
        $this->file = null;
    }
    /**
     * @ORM'PostRemove()
     */
    public function removeUpload()
    {
        if ($file = $this->getAbsolutePath()) {
            unlink($file);
        }
    }
}

夹具:

<?php
// src/User/MyBundle/DataFixtures/ORM/ArtFixtures.php
namespace User'MyBundle'DataFixtures'ORM;
use Doctrine'Common'DataFixtures'AbstractFixture;
use Doctrine'Common'DataFixtures'OrderedFixtureInterface;
use Doctrine'Common'Persistence'ObjectManager;
use Fredzz'LotwBundle'Entity'Art;
use Symfony'Component'HttpFoundation'File'UploadedFile;
class ArtFixtures extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $art1 = new Art();
        $art1->setTitle('MyTitle');
        $art1->setDescription('My description');
        copy($art1->getFixturesPath() . '01.jpg', $art1->getFixturesPath() . '01-copy.jpg');
        $file = new UploadedFile($art1->getFixturesPath() . '01-copy.jpg', 'Image1', null, null, null, true);
        $art1->setFile($file);
        $art1->setUser($manager->merge($this->getReference('user-1')));
        $manager->persist($art1);
        $manager->flush();
    }
}

希望这能帮助到别人!如果出了问题,我很抱歉。我还在学习:)

我找到了问题的答案。我需要使用类Symfony'Component'HttpFoundation'File'File来创建一个文件。Symfony将物理移动文件,而不是创建副本,因此您需要为每个固定装置创建一个新文件,使用copy()创建可以移动的文件副本。

$image = new Image();
$file = new File('path/to/file.jpg');
$image->file = $file;
$om->persist($image);

类似的东西。

您想要使用的图像应该位于"Web"文件夹中,并且您应该只在数据固定装置中使用文件指针字符串(即"/Web/images/test.png")。

您通常应该避免在数据库中存储图像。

我为PHP 5.3+创建了一个FileUpload类

如何使用?:

文档

来自RFC 3023(XML媒体类型):

顶级媒体类型"text"对MIME实体有一些限制并且它们在[RFC2045]和[RFC2046]中进行了描述。特别是不允许使用UTF-16家族、UCS-4和UTF-32(超过HTTP[RFC2616],其使用类似MIME的机制)。

只允许上传yaml文件:

<?php
$file = new FileUpload'FileUpload();
$file->setInput( "file" );
$FileUpload->setAllowedMimeTypes(array(
    "text/x-yaml", //RFC 3023
    "application/x-yaml", // Ruby on Rails
    "text/plain",//Possible option( only text plain )
    "text/yaml",//Possible option
    "text/x-yaml",//Possible option
    "application/yaml",//Possible option
));
$file->setDestinationDirectory("/var/www/html/myapp/");
$file->save();
if ($file->getStatus()) {
    echo "Okay";
}
?>

所有mime类型的示例:

<?php
$file = new FileUpload'FileUpload();
$file->setInput( "file" );
$file->save();
if ($file->getStatus()) {
    echo "is Upload!";
}
?>
<html>
    <head>
        <title>FileUpload Example</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
        <form method="post" action="" enctype="multipart/form-data">
            <input type="file" name="file" />
            <input type="submit" value="Upload now!" />
        </form>
    </body>
</html>

GitHub:https://github.com/olaferlandsen/FileUpload-for-PHP