7

How to find file by name without specific extension in laravel Storage?

like this "filename.*"

Storage::get("filename.*")

I tried this but seems not to work. It searches for specific file with specific extension.

jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
John Roca
  • 1,204
  • 1
  • 14
  • 27
  • Try `Storage::get("filename\.*")` – Rohan Kumar Aug 22 '16 at 05:38
  • @RohanKumar Not working for me. I'm using laravel 5.0. – John Roca Aug 22 '16 at 05:41
  • [This](https://stackoverflow.com/q/29729863/2286722) is a more general version of this question: how to use glob patterns with `Storage`. As `glob` is not available on every system, `Storage` can not directly implement it (although some transparent wrapper would be very welcome!). The solution is a workaround very similar to [the answer by jedrzej.kurylo here](https://stackoverflow.com/a/39072233/2286722): just get the entire list and filter it using RegExp (or some other method). – Marten Koetsier Apr 10 '19 at 07:51

4 Answers4

13

Storage::get() takes a file path as a parameter and returns the content of a single file identified by this path or throws FileNotFoundException if file can't be found.

Wildcards are not supported in the path - one reason for that could be that there might be multiple files that match the path with wildcards which would break the rule that content of a single file is returned from Storage::get(). Scanning the whole folder would also be much slower, especially with remote storages.

However, you could get what you want using other functionality that Storage facade offers. First, list the content of your storage - that will give you the list of all available files. Then filter the list yourself to get the list of matching files.

// list all filenames in given path
$allFiles = Storage::files('');

// filter the ones that match the filename.* 
$matchingFiles = preg_grep('/^filename\./', $allFiles);

// iterate through files and echo their content
foreach ($matchingFiles as $path) {
  echo Storage::get($path);
}
jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
  • 1
    You bit by the buzzer. I was thinking the same solution. Only I got the tweak because of the regex. I removed the ^ to fit my search. Anyways Thank you so much for your time. I'll marked this as correct. Saved my day! – John Roca Aug 22 '16 at 06:08
  • I feel like this answer is prohibitively expensive in terms of memory if you consider a system that uses an AWS S3 bucket with potentially millions of files from millions of users. I really wish there was a way to ask the operating system of the actual storage disk to do the heavy lifting in terms filtering files in a directory listing using wildcards. :/ – fronzee May 04 '22 at 16:51
5

Accepted solution works. However I've found this other and I like it more:

$matchingFiles = \Illuminate\Support\Facades\File::glob("{$path}/*.log");

See reference here: http://laravel-recipes.com/recipes/143/finding-files-matching-a-pattern

mayid
  • 1,644
  • 15
  • 23
  • that reference link is now dead? – Marten Koetsier Apr 07 '19 at 14:57
  • 1
    Seems so. That's why responses don't have to rely on external links. Anyway, there you have the code, and you can always look for "Laravel File::glob" for documentation. Check https://www.php.net/manual/en/function.glob.php, here https://laravel.com/api/5.1/Illuminate/Filesystem/Filesystem.html and maybe here: https://hotexamples.com/examples/illuminate.filesystem/Filesystem/glob/php-filesystem-glob-method-examples.html – mayid Apr 07 '19 at 18:56
  • 1
    thanks....seems working for me `\File::glob(\Storage::disk('profile-picture')->path('/')."*.jpeg");` – Syamsoul Azrien Jan 28 '23 at 09:30
1

Minor change to jedrzej.kurylo's answer and combining wogsland's answer using laravel 8:

'/^filename\./' or '/filename\./' pattern does not work in my case.

// From:

$matchingFiles = preg_grep('/^filename./', $allFiles);

// To:
$allFiles = Storage::disk('yourStorageDisk')->files('folder/path');
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/webp'];
$matchingFiles = preg_grep('{'.$image.'}', $allFiles);

foreach ($matchingFiles as $path) {
    // get real mime type
    $contentType = image_type_to_mime_type(exif_imagetype(asset($path)));

    // compare it with our allowed mime types
    if (in_array($contentType, $allowedMimeTypes)) {
        // do something here...
    }
}

This way we can fetch files or images safely.

Dale Ryan
  • 473
  • 4
  • 9
0

Dont trust what you see. Get inside and get the ext for your file

$pic = 'url/your.file';
$ext = image_type_to_mime_type(exif_imagetype($pic));
$ext = explode('/',$ext);
echo $ext[1];
wogsland
  • 9,106
  • 19
  • 57
  • 93
Tomas
  • 1
  • 1