Jose Jimenez
Jose Jimenez
Software Architect & Developer
> >

Spatie Media Library improved directory listings

Published in Laravel, PHP, Spatie, Performance on Nov 29, 2022

When working on project that will store any type of media on a storage device such as AWS S3 or even a file system, it is a good idea to break out the files into a deeper directory structure. This is to avoid slow directory listings down the road when working with the file structure through a client, server, or other scripts.

Picture having a root directory with thousands of media files, if you attempt to do a directory listing of it it may begin to cause problems for your set up.

For this example I chose the Spatie Media Library as I am a huge fan of the package and it makes it easy to modify the intended location.

By default the library will store generated content in the root level of your storage directory, i.e. let's assume we uploaded a .jpg image and the media gives it the ID of 234, the file by default will live on:

/storage/media/234/file.jpg

However per our previous conversation, once you have ID 102034, that could be 102034 directories that would need to be listed causing problems.

A simple solution is to break out the media into a deep directory path, for this example we will break out the media library into year/month/date/MEDIAID, this would allow you to spread your media directories into the date they were created. Because creation date is static and won't change we can use that as the base for your directories;

app/Support/Vendors/MediaLibrary/PathGenerator.php

 1<?php
 2
3namespace App\Support\Vendors\MediaLibrary;
 4
5use Spatie\MediaLibrary\MediaCollections\Models\Media;
6use Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator;
 7
8class PathGenerator extends DefaultPathGenerator
 9{
10 /*
11 * Get a unique base path for the given media.
12 */
13 protected function getBasePath(Media $media): string
14 {
15 return $media->created_at->format('Y/m/d') . '/'. $media->id;
16 }
17}

Using the above example would generate the directory structure of: 2022/11/29/1/file.jpg

In closing

Although this solution will work for most use cases you could run into a use case in which your application must generate thousands of medias in a single day. In those situations you could expand the function further by breaking out your directory into hundreds, thousands, etc... depending on your specific use case. 2022/11/29/1000/100/20/file.jpg.