Skip to content
A Symfony bundle for hashing filenames and spreading files out across folders
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
Twig Initial commit Feb 16, 2017
.gitignore Initial commit Feb 16, 2017
LICENSE Initial commit Feb 16, 2017 Changes to documentation Feb 16, 2017
composer.json Initial commit Feb 16, 2017
phpunit.xml.dist Initial commit Feb 16, 2017


A Symfony bundle for creating hashed filenames from uploaded files, and spreading them out across directories.

You can set the hashing algorithm you want to use to create filenames, how many folders deep you want the files to be stored, and how many characters to use per folder name. It uses the leading characters in the hashed filename to create the folder names.

For example, given sha1 as your hashing algo, you might get a filename like this:


If you set folder character length: 2, and folder depth: 2, that file would be stored here:


Setting folder character length: 3, and folder depth: 1, would store the file here:


This functionality may be useful for those that do not want to have too many files residing in any single directory.


Step 1: Download the Bundle

Open a command console, enter your project directory and execute the following command:

$ composer require south634/mass-media-bundle "dev-master"

This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.

Step 2: Enable the Bundle

Then, enable the bundle by adding it to the list of registered bundles in the app/AppKernel.php file of your project:

// app/AppKernel.php

// ...
class AppKernel extends Kernel
    public function registerBundles()
        $bundles = array(
            // ...

            new South634\MassMediaBundle\South634MassMediaBundle(),

        // ...

    // ...

Step 3: Add Settings

Finally, configure the required settings as you wish in the app/config/config.yml file of your project.

See example below:

# app/config/config.yml

        hash_algo: sha1
        upload_dir: media        
        folder_depth: 2
        folder_chars: 2

Required Settings:


The hashing algorithm you want to use for filename creation. Must be an algo present in the array returned by the PHP hash_algos() function.


Name of folder where you want to store the uploads. This folder will be created in your Symfony application's web accessible directory.


How many folders deep you want to store the files. Minimum is 0.


How many characters you want to use per folder name. Minimum is 0.

Note: folder_depth * folder_chars should never be greater than your expected filename length. For example, with hash_algo: sha1 you'd expect filename hashes 40 characters long. In that case, you should not set folder_depth: 20 and folder_chars: 3, because 20 * 3 > 40. Your filename would not have enough characters to create the folders.

Optional Settings:


Name of the web accessible directory in your Symfony application. Defaults to 'web'.


Absolute path to the root directory of your Symfony application. Defaults to '%kernel.root_dir%'.



Get the MassMediaManager service in your Controller like so:

$mmm = $this->get('south634_mass_media.manager');

Create a filename from UploadedFile (Prevent duplicate filenames)

$fileName = $mmm->getFileName($file);

This creates a hashed filename from an UploadedFile object.

MassMediaManager uses PHP's hash_file() function to create the filename here. That means that even if you upload two identical files which have different filenames, you should receive the same hashed filename for both of those files.

For example, say you have a cat photo, 'cute-cat.jpg'. You copy that photo elsewhere and rename it, 'kittypic.jpg'. Now, you upload both photos. As the images are still the same, the hash created by hash_file() will be the same them.

This could be useful if you want to cut down on duplicate files being stored on your server. Just be careful to check if a file is owned by any other entities before deleting it.

Create filename from UploadedFile (Allow duplicate files)

If you want to allow uploads of duplicate files, the getFileName() method accepts an optional $unique parameter which can be used to do so. For example, you could create a unique hashed filename for each user by adding the User's id to the file like so:

$fileName = $mmm->getFileName($file, $user->getId());

Using the same example with the 2 identical cat photo files from above, imagine that User 1 uploads 'cute-cat.jpg', while User 2 uploads 'kittypic.jpg'. Even though it's an identical file, their unique user id is added to the hash, which results in a different filename that is unique to each user, and can be stored separately.

Create a Filename from URL

$fileName = $mmm->getFileNameFromUrl($url);

If you want to create a filename from a URL instead of an UploadedFile object, use the getFileNameFromUrl() method instead. This method also excepts the optional 2nd $unique parameter:

$fileName = $mmm->getFileNameFromUrl($url, $unique);

Upload a file


Use uploadFile() to upload an UploadedFile file object. It will create all the necessary folders for this file's path within the upload_dir you set in your config.yml settings. Also, can accept a second optional unique parameter:

$mmm->uploadFile($file, $unique);

Upload File from URL


Same as uploadFile() but for URLs instead of UploadedFile objects. You will need allow_url_fopen enabled to use this. Also, can accept a second optional unique parameter:

$mmm->uploadFileFromUrl($url, $unique);

Remove File


Removes a file, and any empty subdirectories created for that file. Just pass in the filename.

Alternatively, if you want to remove a file, but keep any empty subdirectories created for it, use false as the second parameter to this method like so:

$mmm->removeFile($fileName, false);

Get Web Path


Returns the web path of a file.


To get the web path to your file in a Twig template you can use the mass_media_web_path filter like so:

<img src="{{ asset(|mass_media_web_path) }}">
You can’t perform that action at this time.