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


Upload a file using Symfony2 and a simple form

我试图上传一个文件在我的symfony2项目使用一个简单的形式。我确实阅读了symfony的官方文档,但我只想将我的文件移动到目录并更新数据库表(称为用户)中的字段,而不是为文件创建实体。我使用一个例子,我成功上传,但在。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');
        }
    }

正如Tomasz Turkowski所说,解决方案是使用$file->getClientOriginalName(在类UploadFileMover中)将文件的基本名称改为其真实名称。

class UploadFileMover {
public function moveUploadedFile(UploadedFile $file, $uploadBasePath, $relativePath) 
{
   // $originalName = $file->getFilename();
      $originalName = $file->getClientOriginalName();
        // use filemtime() to have a more determenistic 

无需将.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 }} >

的位置获取此路径。