使用Symfony2和简单表单上传文件

时间:2015-08-25 11:34:05

标签: php symfony

我尝试使用简单的Form在我的symfony2项目中上传文件。 我确实阅读了symfony的官方文档,但我想只将我的文件移动到目录并更新db表(称为用户)中的字段而不是为该文件创建实体。我使用一个例子我成功上传但是在.tmp扩展名(例如phpXXX.tmp)。请任何想法。

这里是我的代码:

Document.php:

use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;


class Document
{

    private $file;

    private $subDir;

    private $filePersistencePath;

    /** @var string */
    protected static $uploadDirectory = '%kernel.root_dir%/../styles/images';

    static public function setUploadDirectory($dir)
    {
        self::$uploadDirectory = $dir;
    }

    static public function getUploadDirectory()
    {
        if (self::$uploadDirectory === null) {
            throw new \RuntimeException("Trying to access upload directory for profile files");
        }
        return self::$uploadDirectory;
    }
    public function setSubDirectory($dir)
    {
         $this->subDir = $dir;
    }

    public function getSubDirectory()
    {
        if ($this->subDir === null) {
            throw new \RuntimeException("Trying to access sub directory for profile files");
        }
        return $this->subDir;
    }


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

    public function getFile()
    {
        return new File(self::getUploadDirectory() . "/" . $this->filePersistencePath);
    }

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

    public function getFilePersistencePath()
    {
        return $this->filePersistencePath;
    }

    public function processFile()
    {
        if (! ($this->file instanceof UploadedFile) ) {
            return false;
        }
        $uploadFileMover = new UploadFileMover();
        $this->filePersistencePath = $uploadFileMover->moveUploadedFile($this->file, self::getUploadDirectory(),$this->subDir);
    }
}

UploadFileMover

 use Symfony\Component\HttpFoundation\File\UploadedFile;

    class UploadFileMover {

        public function moveUploadedFile(UploadedFile $file, $uploadBasePath, $relativePath) {
            $originalName = $file->getFilename();
            // use filemtime() to have a more determenistic way to determine the subpath, otherwise its hard to test.
            // $relativePath = date('Y-m', filemtime($file->getPath()));
            $targetFileName = $relativePath . DIRECTORY_SEPARATOR . $originalName;
            $targetFilePath = $uploadBasePath . DIRECTORY_SEPARATOR . $targetFileName;
            $ext = $file->getExtension();
            $i = 1;
            while (file_exists($targetFilePath) && md5_file($file->getPath()) != md5_file($targetFilePath)) {
                if ($ext) {
                    $prev = $i == 1 ? "" : $i;
                    $targetFilePath = $targetFilePath . str_replace($prev . $ext, $i++ . $ext, $targetFilePath);
                } else {
                    $targetFilePath = $targetFilePath . $i++;
                }
            }
            $targetDir = $uploadBasePath . DIRECTORY_SEPARATOR . $relativePath;
            if (!is_dir($targetDir)) {
                $ret = mkdir($targetDir, umask(), true);
                if (!$ret) {
                    throw new \RuntimeException("Could not create target directory to move temporary file into.");
                }
            }
            $file->move($targetDir, basename($targetFilePath));

            return str_replace($uploadBasePath . DIRECTORY_SEPARATOR, "", $targetFilePath);
        }

    }

controller : 

public function uploadImgAction(Request $req) {
        if ($req->getMethod() == 'POST') {
            $status = 'success';
            $uploadedURL = '';
            $message = 'Image modifiée';

            $image = $req->files->get('fileselect');

            if (($image instanceof UploadedFile) && ($image->getError() == '0')) {
                if ($image->getSize() < 2000000) {
                     $originalName = $image->getClientOriginalName();
                    $name_array = explode('.', $originalName);
                    $file_type = $name_array[sizeof($name_array) - 1];
                    $valid_filetypes = array('jpg', 'jpeg', 'bmp', 'png');
                    if (in_array(strtolower($file_type), $valid_filetypes)) {
                        //télécharegement du fichier
                        //Start Uploading File

                      $document = new Document();
                      $document->setFile($image);
                      $document->setSubDirectory('uploads');
                      $document->processFile();
                      $uploadedURL=$uploadedURL = $document->getUploadDirectory() . DIRECTORY_SEPARATOR . $document->getSubDirectory() . DIRECTORY_SEPARATOR . $image->getBasename();
                   } else {
                        $status = 'echoue';
                        $message = 'Seuls les extensions png, jpg, jpeg et bmp sont acceptées';
                    }
                } else {
                    $status = 'echoue';
                    $message = 'La taille du fichier dépasse 2MB';
                }
            } else {
                $status = 'echoue';
                $message = 'Une erreur de télechargement';
            }

             return $this->render('PIRecrutementBundle:xx:xxx.html.twig');
            //return new Response($uploadedUrl);
        } else {
            return $this->render('xxxBundle:xx:xxx.html.twig');
        }
    }

2 个答案:

答案 0 :(得分:0)

正如Tomasz Turkowski所述解决方案是使用$ file-&gt; getClientOriginalName(在UploadFileMover类中。)改变文件的基本名称。

class UploadFileMover {

public function moveUploadedFile(UploadedFile $file, $uploadBasePath, $relativePath) 
{
   // $originalName = $file->getFilename();
      $originalName = $file->getClientOriginalName();

        // use filemtime() to have a more determenistic 

答案 1 :(得分:0)

如果不将.tmp更改为其他扩展名或原始名称,您仍然可以在DB中存储相同的获取路径。我认为您可以编写一个查询来在控制器中的此语句之后将路径存储在DB中

$uploadedURL=$uploadedURL = $document->getUploadDirectory() . DIRECTORY_SEPARATOR . $document->getSubDirectory() . DIRECTORY_SEPARATOR . $image->getBasename();

使用变量$uploadURL,如

{

//in your methodAction

"Update [YOUR TABLE] SET [PATHcolomn]=".$uploadURL." WHERE USERid=".$user->getUid()." "

$path= "SELECT [PATHcolomN] FROM [YOUR TABLE] WHERE USERid=".$user->getUid()." "

$this->data['path']=$path;

return $this->data;


}

更新后,您可以在<img src= {{ path }} >

的位置获取此路径