kant312
kant312

Reputation: 1394

In Laravel, how can I obtain a list of all files in a public folder?

I'd like to automatically generate a list of all images in my public folder, but I cannot seem to find any object that could help me do this.

The Storage class seems like a good candidate for the job, but it only allows me to search files within the storage folder, which is outside the public folder.

Upvotes: 56

Views: 169399

Answers (12)

youngdero
youngdero

Reputation: 380

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\File;
use Illuminate\Http\Request;

class FileController extends Controller
{
    /**
     * Get all file paths from a public folder.
     *
     * @return array
     */
    public function getAllFilePaths()
    {
        // Define the directory path
        $directoryPath = public_path('your-folder'); // replace 'your-folder' with your actual folder name

        // Get all files in the directory
        $files = File::allFiles($directoryPath);

        // Convert file objects to array of paths
        $filePaths = [];
        foreach ($files as $file) {
            $filePaths[] = $file->getPathname();
        }

        return $filePaths;
    }
}

Explanation:

  • Namespace Import: Ensure that Illuminate\Support\Facades\File is imported to access file system-related operations.
  • Directory Path: Use public_path('your-folder') to specify the folder inside the public directory. Replace 'your-folder' with your specific folder name.
  • Retrieve Files: Use File::allFiles($directoryPath) to retrieve all files. This method returns an array of SplFileInfo objects.
  • Extract Paths: Iterate over the retrieved files and extract their full paths using the getPathname() method.

You can call the getAllFilePaths method to get an array containing the full paths of all files within the specified folder. Adjust the folder name accordingly based on your needs.

Upvotes: 0

Ajmal
Ajmal

Reputation: 101

Use the File Namespace for getting the public path. Then use this code to get all the files from the selected directory.

use File;      

For example the public directory name is "media"

$mediaPath = public_path('media');
$filesInFolder = File::allFiles($mediaPath);
$allMedia = [];


foreach ($filesInFolder as $path) {
    $files = pathinfo($path);
    $allMedia[] = $files['basename'];
}

Upvotes: 8

DEV Tiago Fran&#231;a
DEV Tiago Fran&#231;a

Reputation: 1696

Laravel On-Demand Disks

https://laravel.com/docs/9.x/filesystem#on-demand-disks

use Illuminate\Support\Facades\Storage;
 
$disk = Storage::build([
    'driver' => 'local',
    'root' => '/path/to/root',
]);
 
$disk->put('image.jpg', $content);

Additionaly, you can use files or allFiles methods to get files from another directories.

Both returns array, but files allow recursive way.

>>> man $disk->allFiles
class Illuminate\Filesystem\FilesystemAdapter implements Illuminate\Contracts\Filesystem\Cloud, Illuminate\Contracts\Filesystem\Filesystem
public function allFiles($directory = null)

Description:
  Get all of the files from the given directory (recursive).

Param:
  string|null  $directory 

Return:
  array 
>>> man $disk->files
class Illuminate\Filesystem\FilesystemAdapter implements Illuminate\Contracts\Filesystem\Cloud, Illuminate\Contracts\Filesystem\Filesystem
public function files($directory = null, $recursive = false)

Description:
  Get an array of all files in a directory.

Param:
  string|null  $directory 
  bool         $recursive 

Return:
  array 
>>> 

Upvotes: 0

Joukhar
Joukhar

Reputation: 872

in laravel just use :

use Illuminate\Support\Facades\File;

    $path = public_path();
    $files = File::allFiles($path);
  
    dd($files);

i hope it was useful !

Upvotes: 5

Tarek Adam
Tarek Adam

Reputation: 3525

Storage::disk('local')->files('optional_dir_name');

or just a certain type of file

array_filter(Storage::disk('local')->files(), function ($item) {
   //only png's
   return strpos($item, '.png');
});

Note that laravel disk has files() and allfiles(). allfiles is recursive.

Upvotes: 58

drmarvelous
drmarvelous

Reputation: 1681

Consider using glob. No need to overcomplicate barebones PHP with helper classes/methods in Laravel 5.

<?php
foreach (glob("/location/for/public/images/*.png") as $filename) {
    echo "$filename size " . filesize($filename) . "\n";
}
?>

Upvotes: 32

igs013
igs013

Reputation: 1420

You could create another disk for Storage class. This would be the best solution for you in my opinion.

In config/filesystems.php in the disks array add your desired folder. The public folder in this case.

    'disks' => [

    'local' => [
        'driver' => 'local',
        'root'   => storage_path().'/app',
    ],

    'public' => [
        'driver' => 'local',
        'root'   => public_path(),
    ],

    's3' => '....'

Then you can use Storage class to work within your public folder in the following way:

$exists = Storage::disk('public')->exists('file.jpg');

The $exists variable will tell you if file.jpg exists inside the public folder because the Storage disk 'public' points to public folder of project.

You can use all the Storage methods from documentation, with your custom disk. Just add the disk('public') part.

 Storage::disk('public')-> // any method you want from 

http://laravel.com/docs/5.0/filesystem#basic-usage

Later Edit:

People complained that my answer is not giving the exact method to list the files, but my intention was never to drop a line of code that the op copy / paste into his project. I wanted to "teach" him, if I can use that word, how to use the laravel Storage, rather then just pasting some code.

Anyway, the actual methods for listing the files are:

$files = Storage::disk('public')->files($directory);

// Recursive...
$files = Storage::disk('public')->allFiles($directory);

And the configuration part and background are above, in my original answer.

Upvotes: 77

bmatovu
bmatovu

Reputation: 4074

You can use FilesystemReader::listContents

Storage::disk('public')->listContents();

Sample response...

[
  [
    "type" => "file",
    "path" => ".gitignore",
    "timestamp" => 1600098847,
    "size" => 27,
    "dirname" => "",
    "basename" => ".gitignore",
    "extension" => "gitignore",
    "filename" => "",
  ],
  [
    "type" => "dir",
    "path" => "avatars",
    "timestamp" => 1600187489,
    "dirname" => "",
    "basename" => "avatars",
    "filename" => "avatars",
  ]
]

Upvotes: 7

Paul Preibisch
Paul Preibisch

Reputation: 4322

You can get all the files doing:

use Illuminate\Support\Facades\Storage;

..

$files = Storage::disk('local')->allFiles('public');

Upvotes: 3

Liz Eipe C
Liz Eipe C

Reputation: 255

Please use the following code and get all the subdirectories of a particular folder in the public folder. When some click the folder it lists the files inside each folder.

Controller File

 public function index() {

    try {

        $dirNames = array();  
        $this->folderPath = 'export'.DS.str_replace( '.', '_', $this->getCurrentShop->getCurrentShop()->shopify_domain ).DS.'exported_files';
        $getAllDirs = File::directories( public_path( $this->folderPath ) );

        foreach( $getAllDirs as $dir ) {

            $dirNames[] = basename($dir);

        }
        return view('backups/listfolders', compact('dirNames'));

    } catch ( Exception $ex ) {
        Log::error( $ex->getMessage() );
    }



}

public function getFiles( $directoryName ) {

    try {
        $filesArr = array();
        $this->folderPath = 'export'.DS.str_replace( '.', '_', $this->getCurrentShop->getCurrentShop()->shopify_domain ).DS.'exported_files'. DS . $directoryName;
        $folderPth = public_path( $this->folderPath );
        $files = File::allFiles( $folderPth ); 
        $replaceDocPath = str_replace( public_path(),'',$this->folderPath );

        foreach( $files as $file ) {

            $filesArr[] = array( 'fileName' => $file->getRelativePathname(), 'fileUrl' => url($replaceDocPath.DS.$file->getRelativePathname()) );

        }

        return view('backups/listfiles', compact('filesArr'));

    } catch (Exception $ex) {
        Log::error( $ex->getMessage() );
    }


}

Route ( Web.php )

Route::resource('displaybackups', 'Displaybackups\BackupController')->only([ 'index', 'show']);

Route::get('get-files/{directoryName}', 'Displaybackups\BackupController@getFiles');

View files - List Folders

@foreach( $dirNames as $dirName)
    <div class="col-lg-3 col-md-3 col-sm-4 align-center">
        <a href="get-files/{{$dirName}}" class="btn btn-light folder-wrap" role="button">
            <span class="glyphicon glyphicon-folder-open folderIcons"></span>
            {{ $dirName }}
        </a>
    </div>
@endforeach

View - List Files

@foreach( $filesArr as $fileArr)
    <div class="col-lg-2 col-md-3 col-sm-4">
        <a href="{{ $fileArr['fileUrl'] }}" class="waves-effect waves-light btn green folder-wrap">
            <span class="glyphicon glyphicon-file folderIcons"></span>
            <span class="file-name">{{ $fileArr['fileName'] }}</span>
        </a>
    </div>
@endforeach

Upvotes: 1

Adnan Rasheed
Adnan Rasheed

Reputation: 876

To list all files in directory use this

  $dir_path = public_path() . '/dirname';
   $dir = new DirectoryIterator($dir_path);
  foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {

    }
    else {

    }
}

Upvotes: 6

Toskan
Toskan

Reputation: 14931

To list all images in your public dir try this: see here btw http://php.net/manual/en/class.splfileinfo.php

  function getImageRelativePathsWfilenames(){

      $result = [];

    $dirs = File::directories(public_path());

    foreach($dirs as $dir){
      var_dump($dir); //actually string: /home/mylinuxiser/myproject/public"
      $files = File::files($dir);
      foreach($files as $f){
        var_dump($f); //actually object SplFileInfo
        //object(Symfony\Component\Finder\SplFileInfo)#628 (4) {
        //["relativePath":"Symfony\Component\Finder\SplFileInfo":private]=>
        //string(0) ""
        //["relativePathname":"Symfony\Component\Finder\SplFileInfo":private]=>
        //string(14) "text1_logo.png"
        //["pathName":"SplFileInfo":private]=>
        //string(82) "/home/mylinuxiser/myproject/public/img/text1_logo.png"
        //["fileName":"SplFileInfo":private]=>
        //string(14) "text1_logo.png"
        //}

        if(ends_with($f, ['.png', '.jpg', '.jpeg', '.gif'])){
          $result[] = $f->getRelativePathname(); //prefix your public folder here if you want
        }
      }
    }
    return $result; //will be in this case ['img/text1_logo.png']
  }

Upvotes: 2

Related Questions