Search code examples
phpsymfonysymfony-2.6symfony-http-foundation

Get file extension after file is uploaded and moved in Symfony2


I'm uploading a file through Symfony2 and I am trying to rename original in order to avoid override the same file. This is what I am doing:

$uploadedFile = $request->files;
$uploadPath = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/';

try {
    $uploadedFile->get('avatar')->move($uploadPath, $uploadedFile->get('avatar')->getClientOriginalName());
} catch (\ Exception $e) {
    // set error 'can not upload avatar file'
}

// this get right filename
$avatarName = $uploadedFile->get('avatar')->getClientOriginalName();
// this get wrong extension meaning empty, why? 
$avatarExt = $uploadedFile->get('avatar')->getExtension();

$resource = fopen($uploadPath . $uploadedFile->get('avatar')->getClientOriginalName(), 'r');
unlink($uploadPath . $uploadedFile->get('avatar')->getClientOriginalName());

I am renaming file as follow:

$avatarName = sptrinf("%s.%s", uniqid(), $uploadedFile->get('avatar')->getExtension());

But $uploadedFile->get('avatar')->getExtension() is not giving me the extension of the uploaded file so I give a wrong filename like jdsfhnhjsdf. without extension, Why? What is the right way to rename file after or before move to the end path? Any advice?


Solution

  • Well, the solution is really simple if you know it.

    Since you moved the UploadedFile, the current object instance cannot be used anymore. The file no longer exists, and so the getExtension will return in null. The new file instance is returned from the move.

    Change your code to (refactored for clarity):

        $uploadPath = $this->container->getParameter('kernel.root_dir') . '/../web/uploads/';
    
        try {
            $uploadedAvatarFile = $request->files->get('avatar');
    
            /* @var $avatarFile \Symfony\Component\HttpFoundation\File\File */
            $avatarFile = $uploadedAvatarFile->move($uploadPath, $uploadedAvatarFile->getClientOriginalName());
    
            unset($uploadedAvatarFile);
        } catch (\Exception $e) {
            /* if you don't set $avatarFile to a default file here
             * you cannot execute the next instruction.
             */
        }
    
        $avatarName = $avatarFile->getBasename();
        $avatarExt = $avatarFile->getExtension();
    
        $openFile = $avatarFile->openFile('r');
        while (! $openFile->eof()) {
            $line = $openFile->fgets();
            // do something here...
        }
        // close the file
        unset($openFile);
        unlink($avatarFile->getRealPath());
    

    (Code not tested, just wrote it) Hope it helps!