1

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?

ReynierPM
  • 17,594
  • 53
  • 193
  • 363

1 Answers1

4

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!

giosh94mhz
  • 2,908
  • 14
  • 25
  • Just one thing that I don't know why happen: `Warning: fclose(): 78 is not a valid stream resource` otherwise works perfectly – ReynierPM May 29 '15 at 14:53
  • Strange, since `fopen` return a resource on success and `FALSE` on failure. Maybe the file is already closed, so php triggers a warning? – giosh94mhz May 29 '15 at 14:57
  • Also note that a symfony `File` is a subtype of `SplFileInfo` so can just use `$avatarFile->openFile('r')`.... I'll update my answer to show you the "proper" way – giosh94mhz May 29 '15 at 15:01